home *** CD-ROM | disk | FTP | other *** search
/ Mac Power 1997 December / MACPOWER-1997-12.ISO.7z / MACPOWER-1997-12.ISO / AMUG / PROGRAMMING / Raven 1.2.sit / Raven 1.2 / • Extras • / SGI STL / algo.h next >
C/C++ Source or Header  |  1997-05-28  |  101KB  |  2,761 lines

  1. /*
  2.  *
  3.  * Copyright (c) 1994
  4.  * Hewlett-Packard Company
  5.  *
  6.  * Permission to use, copy, modify, distribute and sell this software
  7.  * and its documentation for any purpose is hereby granted without fee,
  8.  * provided that the above copyright notice appear in all copies and
  9.  * that both that copyright notice and this permission notice appear
  10.  * in supporting documentation.  Hewlett-Packard Company makes no
  11.  * representations about the suitability of this software for any
  12.  * purpose.  It is provided "as is" without express or implied warranty.
  13.  *
  14.  *
  15.  * Copyright (c) 1996
  16.  * Silicon Graphics Computer Systems, Inc.
  17.  *
  18.  * Permission to use, copy, modify, distribute and sell this software
  19.  * and its documentation for any purpose is hereby granted without fee,
  20.  * provided that the above copyright notice appear in all copies and
  21.  * that both that copyright notice and this permission notice appear
  22.  * in supporting documentation.  Silicon Graphics makes no
  23.  * representations about the suitability of this software for any
  24.  * purpose.  It is provided "as is" without express or implied warranty.
  25.  *
  26.  * Exception Handling:
  27.  * Copyright (c) 1997
  28.  * Mark of the Unicorn, Inc.
  29.  *
  30.  * Permission to use, copy, modify, distribute and sell this software
  31.  * and its documentation for any purpose is hereby granted without fee,
  32.  * provided that the above copyright notice appear in all copies and
  33.  * that both that copyright notice and this permission notice appear
  34.  * in supporting documentation.  Mark of the Unicorn makes no
  35.  * representations about the suitability of this software for any
  36.  * purpose.  It is provided "as is" without express or implied warranty.
  37.  *
  38.  * Adaptation:
  39.  * Copyright (c) 1997
  40.  * Moscow Center for SPARC Technology
  41.  *
  42.  * Permission to use, copy, modify, distribute and sell this software
  43.  * and its documentation for any purpose is hereby granted without fee,
  44.  * provided that the above copyright notice appear in all copies and
  45.  * that both that copyright notice and this permission notice appear
  46.  * in supporting documentation.  Moscow Center for SPARC Technology makes no
  47.  * representations about the suitability of this software for any
  48.  * purpose.  It is provided "as is" without express or implied warranty.
  49.  *
  50.  */
  51.  
  52. #ifndef __SGI_STL_ALGO_H
  53. #define __SGI_STL_ALGO_H
  54.  
  55. #include <stdlib.h>
  56. #include <limits.h>
  57. # ifndef __SGI_STL_ALGOBASE_H
  58. #  include <algobase.h>
  59. # endif
  60. # ifndef __SGI_STL_HEAP_H
  61. #  include <heap.h>
  62. # endif
  63. # ifndef __SGI_STL_TEMPBUF_H
  64. #  include <tempbuf.h>
  65. # endif
  66.  
  67. __BEGIN_STL_NAMESPACE
  68.  
  69. template <class T>
  70. inline const T& __median(const T& a, const T& b, const T& c) {
  71.     if (a < b)
  72.         if (b < c)
  73.             return b;
  74.         else if (a < c)
  75.             return c;
  76.         else
  77.             return a;
  78.     else if (a < c)
  79.         return a;
  80.     else if (b < c)
  81.         return c;
  82.     else
  83.         return b;
  84. }
  85.  
  86. template <class T, class Compare>
  87. inline const T& __median(const T& a, const T& b, const T& c, Compare comp) {
  88.     if (comp(a, b))
  89.         if (comp(b, c))
  90.             return b;
  91.         else if (comp(a, c))
  92.             return c;
  93.         else
  94.             return a;
  95.     else if (comp(a, c))
  96.         return a;
  97.     else if (comp(b, c))
  98.         return c;
  99.     else
  100.         return b;
  101. }
  102.  
  103. template <class InputIterator, class Function>
  104. Function for_each(InputIterator first, InputIterator last, Function f) {
  105.     __stl_debug_check(__check_range(first, last));
  106.     for (;first != last;++first) f(*first);
  107.     return f;
  108. }
  109.  
  110. template <class InputIterator, class T>
  111. InputIterator find(InputIterator first, InputIterator last, const T& value) {
  112.     __stl_debug_check(__check_range(first, last));
  113.     while (first != last && *first != value) ++first;
  114.     return first;
  115. }
  116.  
  117. template <class InputIterator, class Predicate>
  118. InputIterator find_if(InputIterator first, InputIterator last,
  119.                       Predicate pred) {
  120.     __stl_debug_check(__check_range(first, last));
  121.     while (first != last && !pred(*first)) ++first;
  122.     return first;
  123. }
  124.  
  125. template <class ForwardIterator>
  126. ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last) {
  127.     __stl_debug_check(__check_range(first, last));
  128.     if (first == last) return last;
  129.     ForwardIterator next = first;
  130.     while(++next != last) {
  131.         if (*first == *next) return first;
  132.         first = next;
  133.     }
  134.     return last;
  135. }
  136.  
  137. template <class ForwardIterator, class BinaryPredicate>
  138. ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last,
  139.                               BinaryPredicate binary_pred) {
  140.     __stl_debug_check(__check_range(first, last));
  141.     if (first == last) return last;
  142.     ForwardIterator next = first;
  143.     while(++next != last) {
  144.         if (binary_pred(*first, *next)) return first;
  145.         first = next;
  146.     }
  147.     return last;
  148. }
  149.  
  150. template <class InputIterator, class T, class Size>
  151. void count(InputIterator first, InputIterator last, const T& value,
  152.            Size& n) {
  153.     __stl_debug_check(__check_range(first, last));
  154.     for (; first != last; ++first)
  155.         if (*first == value) ++n;
  156. }
  157.  
  158. template <class InputIterator, class Predicate, class Size>
  159. void count_if(InputIterator first, InputIterator last, Predicate pred,
  160.               Size& n) {
  161.     __stl_debug_check(__check_range(first, last));
  162.     for (;first != last;++first)
  163.         if (pred(*first)) ++n;
  164. }
  165.  
  166. template <class ForwardIterator1, class ForwardIterator2, class Distance1,
  167.                   class Distance2>
  168. ForwardIterator1 __search(ForwardIterator1 first1, ForwardIterator1 last1,
  169.                           ForwardIterator2 first2, ForwardIterator2 last2,
  170.                           Distance1*, Distance2*) {
  171.     Distance1 d1 = 0;
  172.     distance(first1, last1, d1);
  173.     Distance2 d2 = 0;
  174.     distance(first2, last2, d2);
  175.  
  176.     if (d1 < d2) return last1;
  177.  
  178.     ForwardIterator1 current1 = first1;
  179.     ForwardIterator2 current2 = first2;
  180.  
  181.     while (current2 != last2)
  182.         if (*current1++ != *current2++)
  183.             if (d1-- == d2)
  184.                 return last1;
  185.             else {
  186.                 current1 = ++first1;
  187.                 current2 = first2;
  188.             }
  189.     return (current2 == last2) ? first1 : last1;
  190. }
  191.  
  192. template <class ForwardIterator1, class ForwardIterator2>
  193. inline ForwardIterator1 search(ForwardIterator1 first1, ForwardIterator1 last1,
  194.                                ForwardIterator2 first2, ForwardIterator2 last2)
  195. {
  196.     __stl_debug_check(__check_range(first1, last1));
  197.     __stl_debug_check(__check_range(first2, last2));
  198.     return __search(first1, last1, first2, last2, distance_type(first1),
  199.                     distance_type(first2));
  200. }
  201.  
  202. template <class ForwardIterator1, class ForwardIterator2,
  203.     class BinaryPredicate, class Distance1, class Distance2>
  204. ForwardIterator1 __search(ForwardIterator1 first1, ForwardIterator1 last1,
  205.                           ForwardIterator2 first2, ForwardIterator2 last2,
  206.                           BinaryPredicate binary_pred, Distance1*, Distance2*) {
  207.     Distance1 d1 = 0;
  208.     distance(first1, last1, d1);
  209.     Distance2 d2 = 0;
  210.     distance(first2, last2, d2);
  211.  
  212.     if (d1 < d2) return last1;
  213.  
  214.     ForwardIterator1 current1 = first1;
  215.     ForwardIterator2 current2 = first2;
  216.  
  217.     while (current2 != last2)
  218.         if (!binary_pred(*current1++, *current2++))
  219.             if (d1-- == d2)
  220.                 return last1;
  221.             else {
  222.                 current1 = ++first1;
  223.                 current2 = first2;
  224.             }
  225.     return (current2 == last2) ? first1 : last1;
  226. }
  227.  
  228. template <class ForwardIterator1, class ForwardIterator2,
  229.                               class BinaryPredicate>
  230. inline ForwardIterator1 search(ForwardIterator1 first1, ForwardIterator1 last1,
  231.                                ForwardIterator2 first2, ForwardIterator2 last2,
  232.                                BinaryPredicate binary_pred) {
  233.     __stl_debug_check(__check_range(first1, last1));
  234.     __stl_debug_check(__check_range(first2, last2));
  235.     return __search(first1, last1, first2, last2, binary_pred,
  236.                     distance_type(first1), distance_type(first2));
  237. }
  238.  
  239. template <class ForwardIterator1, class ForwardIterator2>
  240. ForwardIterator2 swap_ranges(ForwardIterator1 first1, ForwardIterator1 last1,
  241.                              ForwardIterator2 first2) {
  242.     __stl_debug_check(__check_range(first1, last1));
  243.     for (;first1 != last1;++first1,++first2) iter_swap(first1, first2);
  244.     return first2;
  245. }
  246.  
  247. template <class InputIterator, class OutputIterator, class UnaryOperation>
  248. OutputIterator transform(InputIterator first, InputIterator last,
  249.                          OutputIterator result, UnaryOperation op) {
  250.     __stl_debug_check(__check_range(first, last));
  251.     for (;first != last;++first,++result) *result = op(*first);
  252.     return result;
  253. }
  254.  
  255. template <class InputIterator1, class InputIterator2, class OutputIterator,
  256.                              class BinaryOperation>
  257. OutputIterator transform(InputIterator1 first1, InputIterator1 last1,
  258.                          InputIterator2 first2, OutputIterator result,
  259.                          BinaryOperation binary_op) {
  260.     __stl_debug_check(__check_range(first1, last1));
  261.     for (;first1 != last1;++first1,++first2,++result) *result = binary_op(*first1, *first2);
  262.     return result;
  263. }
  264.  
  265. template <class ForwardIterator, class T>
  266. void replace(ForwardIterator first, ForwardIterator last, const T& old_value,
  267.              const T& new_value) {
  268.     __stl_debug_check(__check_range(first, last));
  269.     while (first != last) {
  270.         if (*first == old_value) *first = new_value;
  271.         ++first;
  272.     }
  273. }
  274.  
  275. template <class ForwardIterator, class Predicate, class T>
  276. void replace_if(ForwardIterator first, ForwardIterator last, Predicate pred,
  277.                 const T& new_value) {
  278.     __stl_debug_check(__check_range(first, last));
  279.     while (first != last) {
  280.         if (pred(*first)) *first = new_value;
  281.         ++first;
  282.     }
  283. }
  284.  
  285. template <class InputIterator, class OutputIterator, class T>
  286. OutputIterator replace_copy(InputIterator first, InputIterator last,
  287.                             OutputIterator result, const T& old_value,
  288.                             const T& new_value) {
  289.     __stl_debug_check(__check_range(first, last));
  290.     for (;first != last;++first,++result) {
  291.         *result = *first == old_value ? new_value : *first;
  292.     }
  293.     return result;
  294. }
  295.  
  296. template <class Iterator, class OutputIterator, class Predicate, class T>
  297. OutputIterator replace_copy_if(Iterator first, Iterator last,
  298.                                OutputIterator result, Predicate pred,
  299.                                const T& new_value) {
  300.     __stl_debug_check(__check_range(first, last));
  301.     for (; first != last; ++first,++result) {
  302.         *result = pred(*first) ? new_value : *first;
  303.     }
  304.     return result;
  305. }
  306.  
  307. template <class ForwardIterator, class Generator>
  308. void generate(ForwardIterator first, ForwardIterator last, Generator gen) {
  309.     __stl_debug_check(__check_range(first, last));
  310.     for (; first != last; ++first) *first = gen();
  311. }
  312.  
  313. template <class OutputIterator, class Size, class Generator>
  314. OutputIterator generate_n(OutputIterator first, Size n, Generator gen) {
  315.     for (; n > 0; --n, ++first) *first = gen();
  316.     return first;
  317. }
  318.  
  319. template <class InputIterator, class OutputIterator, class T>
  320. OutputIterator remove_copy(InputIterator first, InputIterator last,
  321.                            OutputIterator result, const T& value) {
  322.     __stl_debug_check(__check_range(first, last));
  323.     for (; first != last; ++first) {
  324.         if (*first != value)  { 
  325.             *result = *first;
  326.             ++result;
  327.         }
  328.     }
  329.     return result;
  330. }
  331.  
  332. template <class InputIterator, class OutputIterator, class Predicate>
  333. OutputIterator remove_copy_if(InputIterator first, InputIterator last,
  334.                               OutputIterator result, Predicate pred) {
  335.     __stl_debug_check(__check_range(first, last));
  336.     for (; first != last; ++first) {
  337.         if (!pred(*first)) {
  338.             *result = *first;
  339.             ++result;
  340.         }
  341.     }
  342.     return result;
  343. }
  344.  
  345. template <class ForwardIterator, class T>
  346. ForwardIterator remove(ForwardIterator first, ForwardIterator last,
  347.                        const T& value) {
  348.     __stl_debug_check(__check_range(first, last));
  349.     first = find(first, last, value);
  350.     ForwardIterator next = first;
  351.     return first == last ? first : remove_copy(++next, last, first, value);
  352. }
  353.  
  354. template <class ForwardIterator, class Predicate>
  355. ForwardIterator remove_if(ForwardIterator first, ForwardIterator last,
  356.                           Predicate pred) {
  357.     __stl_debug_check(__check_range(first, last));
  358.     first = find_if(first, last, pred);
  359.     ForwardIterator next = first;
  360.     return first == last ? first : remove_copy_if(++next, last, first, pred);
  361. }
  362.  
  363. template <class InputIterator, class ForwardIterator>
  364. ForwardIterator __unique_copy(InputIterator first, InputIterator last,
  365.                               ForwardIterator result, forward_iterator_tag) {
  366.     *result = *first;
  367.     while (++first != last)
  368.         if (*result != *first) *++result = *first;
  369.     return ++result;
  370. }
  371.  
  372. template <class InputIterator, class BidirectionalIterator>
  373. inline BidirectionalIterator __unique_copy(InputIterator first, 
  374.                                            InputIterator last,
  375.                                            BidirectionalIterator result, 
  376.                                            bidirectional_iterator_tag) {
  377.     return __unique_copy(first, last, result, forward_iterator_tag());
  378. }
  379.  
  380. template <class InputIterator, class RandomAccessIterator>
  381. inline RandomAccessIterator __unique_copy(InputIterator first, 
  382.                                           InputIterator last,
  383.                                           RandomAccessIterator result, 
  384.                                           random_access_iterator_tag) {
  385.     return __unique_copy(first, last, result, forward_iterator_tag());
  386. }
  387.  
  388. template <class InputIterator, class OutputIterator, class T>
  389. OutputIterator __unique_copy(InputIterator first, InputIterator last,
  390.                              OutputIterator result, T*) {
  391.     T value = *first;
  392.     *result = value;
  393.     while (++first != last)
  394.         if (value != *first) {
  395.             value = *first;
  396.             *++result = value;
  397.         }
  398.     return ++result;
  399. }
  400.  
  401. template <class InputIterator, class OutputIterator>
  402. inline OutputIterator __unique_copy(InputIterator first, InputIterator last,
  403.                                     OutputIterator result, 
  404.                                     output_iterator_tag) {
  405.     return __unique_copy(first, last, result, value_type(first));
  406. }
  407.  
  408. template <class InputIterator, class OutputIterator>
  409. inline OutputIterator unique_copy(InputIterator first, InputIterator last,
  410.                                   OutputIterator result) {
  411.     __stl_debug_check(__check_range(first, last));
  412.     if (first == last) return result;
  413.     return __unique_copy(first, last, result, iterator_category(result));
  414. }
  415. template <class InputIterator, class ForwardIterator, class BinaryPredicate>
  416. ForwardIterator __unique_copy(InputIterator first, InputIterator last,
  417.                               ForwardIterator result, 
  418.                               BinaryPredicate binary_pred,
  419.                               forward_iterator_tag) {
  420.     *result = *first;
  421.     while (++first != last)
  422.         if (!binary_pred(*result, *first)) *++result = *first;
  423.     return ++result;
  424. }
  425.  
  426. template <class InputIterator, class BidirectionalIterator,
  427.                                   class BinaryPredicate>
  428. inline BidirectionalIterator __unique_copy(InputIterator first, 
  429.                                            InputIterator last,
  430.                                            BidirectionalIterator result, 
  431.                                            BinaryPredicate binary_pred,
  432.                                            bidirectional_iterator_tag) {
  433.     return __unique_copy(first, last, result, binary_pred,
  434.                          forward_iterator_tag());
  435. }
  436.  
  437. template <class InputIterator, class RandomAccessIterator,
  438.                                                class BinaryPredicate>
  439. inline RandomAccessIterator __unique_copy(InputIterator first, 
  440.                                           InputIterator last,
  441.                                           RandomAccessIterator result, 
  442.                                           BinaryPredicate binary_pred,
  443.                                           random_access_iterator_tag) {
  444.     return __unique_copy(first, last, result, binary_pred, 
  445.                          forward_iterator_tag());
  446. }
  447.  
  448. template <class InputIterator, class OutputIterator, class BinaryPredicate,
  449.                                               class T>
  450. OutputIterator __unique_copy(InputIterator first, InputIterator last,
  451.                              OutputIterator result,
  452.                              BinaryPredicate binary_pred, T*) {
  453.     T value = *first;
  454.     *result = value;
  455.     while (++first != last)
  456.         if (!binary_pred(value, *first)) {
  457.             value = *first;
  458.             *++result = value;
  459.         }
  460.     return ++result;
  461. }
  462.  
  463. template <class InputIterator, class OutputIterator, class BinaryPredicate>
  464. inline OutputIterator __unique_copy(InputIterator first, InputIterator last,
  465.                                     OutputIterator result,
  466.                                     BinaryPredicate binary_pred,
  467.                                     output_iterator_tag) {
  468.     return __unique_copy(first, last, result, binary_pred, value_type(first));
  469. }
  470.  
  471. template <class InputIterator, class OutputIterator, class BinaryPredicate>
  472. inline OutputIterator unique_copy(InputIterator first, InputIterator last,
  473.                                   OutputIterator result,
  474.                                   BinaryPredicate binary_pred) {
  475.     __stl_debug_check(__check_range(first, last));
  476.     if (first == last) return result;
  477.     return __unique_copy(first, last, result, binary_pred,
  478.                          iterator_category(result));
  479. }
  480.  
  481. template <class ForwardIterator>
  482. ForwardIterator unique(ForwardIterator first, ForwardIterator last) {
  483.     __stl_debug_check(__check_range(first, last));
  484.     first = adjacent_find(first, last);
  485.     return unique_copy(first, last, first);
  486. }
  487.  
  488. template <class ForwardIterator, class BinaryPredicate>
  489. ForwardIterator unique(ForwardIterator first, ForwardIterator last,
  490.                        BinaryPredicate binary_pred) {
  491.     __stl_debug_check(__check_range(first, last));
  492.     first = adjacent_find(first, last, binary_pred);
  493.     return unique_copy(first, last, first, binary_pred);
  494. }
  495.  
  496. template <class BidirectionalIterator>
  497. void __reverse(BidirectionalIterator first, BidirectionalIterator last, 
  498.                bidirectional_iterator_tag) {
  499.     while (true)
  500.         if (first == last || first == --last)
  501.             return;
  502.         else {
  503.             iter_swap(first, last);
  504.             ++first;
  505.         }
  506. }
  507.  
  508. template <class RandomAccessIterator>
  509. void __reverse(RandomAccessIterator first, RandomAccessIterator last,
  510.                random_access_iterator_tag) {
  511.     for (; first < last; ++first) iter_swap(first, --last);
  512. }
  513.  
  514. template <class BidirectionalIterator>
  515. inline void reverse(BidirectionalIterator first, BidirectionalIterator last) {
  516.     __stl_debug_check(__check_range(first, last));
  517.     __reverse(first, last, iterator_category(first));
  518. }
  519.  
  520. template <class BidirectionalIterator, class OutputIterator>
  521. INLINE_LOOP OutputIterator reverse_copy(BidirectionalIterator first,
  522.                                         BidirectionalIterator last,
  523.                                         OutputIterator result) {
  524.     __stl_debug_check(__check_range(first, last));
  525.     for (; first != last; ++result) *result = *--last;
  526.     return result;
  527. }
  528.  
  529. template <class ForwardIterator, class Distance>
  530. void __rotate(ForwardIterator first, ForwardIterator middle,
  531.               ForwardIterator last, Distance*, forward_iterator_tag) {
  532.     for (ForwardIterator i = middle; ;) {
  533.         iter_swap(first, i);
  534.         ++first;
  535.         ++i;
  536.         if (first == middle) {
  537.             if (i == last) return;
  538.             middle = i;
  539.         } else if (i == last)
  540.             i = middle;
  541.     }
  542. }
  543.  
  544. template <class BidirectionalIterator, class Distance>
  545. void __rotate(BidirectionalIterator first, BidirectionalIterator middle,
  546.               BidirectionalIterator last, Distance*,
  547.               bidirectional_iterator_tag) {
  548.     reverse(first, middle);
  549.     reverse(middle, last);
  550.     reverse(first, last);
  551. }
  552.  
  553. template <class EuclideanRingElement>
  554. EuclideanRingElement __gcd(EuclideanRingElement m, EuclideanRingElement n)
  555. {
  556.     while (n != 0) {
  557.         EuclideanRingElement t = m % n;
  558.         m = n;
  559.         n = t;
  560.     }
  561.     return m;
  562. }
  563.  
  564. template <class RandomAccessIterator, class Distance, class T>
  565. void __rotate_cycle(RandomAccessIterator first, RandomAccessIterator last,
  566.                     RandomAccessIterator initial, Distance shift, T*) {
  567.     T value = *initial;
  568.     RandomAccessIterator ptr1 = initial;
  569.     RandomAccessIterator ptr2 = ptr1 + shift;
  570.     while (ptr2 != initial) {
  571.         *ptr1 = *ptr2;
  572.         ptr1 = ptr2;
  573.         if (last - ptr2 > shift)
  574.             ptr2 += shift;
  575.         else
  576.             ptr2 = first + (shift - (last - ptr2));
  577.     }
  578.     *ptr1 = value;
  579. }
  580.  
  581. template <class RandomAccessIterator, class Distance>
  582. INLINE_LOOP void __rotate(RandomAccessIterator first, RandomAccessIterator middle,
  583.                           RandomAccessIterator last, Distance*,
  584.                           random_access_iterator_tag) {
  585.     Distance n = __gcd(last - first, middle - first);
  586.     while (n--)
  587.         __rotate_cycle(first, last, first + n, middle - first,
  588.                        value_type(first));
  589. }
  590.  
  591. template <class ForwardIterator>
  592. inline void rotate(ForwardIterator first, ForwardIterator middle,
  593.                    ForwardIterator last) {
  594.     __stl_debug_check(__check_range(middle,first, last));
  595.     if (first == middle || middle == last) return;
  596.     __rotate(first, middle, last, distance_type(first),
  597.              iterator_category(first));
  598. }
  599.  
  600. template <class ForwardIterator, class OutputIterator>
  601. OutputIterator rotate_copy(ForwardIterator first, ForwardIterator middle,
  602.                            ForwardIterator last, OutputIterator result) {
  603.     __stl_debug_check(__check_range(middle, first, last));
  604.     return copy(first, middle, copy(middle, last, result));
  605. }
  606.  
  607. template <class RandomAccessIterator, class Distance>
  608. void __random_shuffle(RandomAccessIterator first, RandomAccessIterator last,
  609.                       Distance*) {
  610.     if (first == last) return;
  611.     for (RandomAccessIterator i = first + 1; i != last; ++i)
  612.         iter_swap(i, first + Distance(__rand() % ((i - first) + 1)));
  613. }
  614.  
  615. template <class RandomAccessIterator>
  616. inline void random_shuffle(RandomAccessIterator first,
  617.                            RandomAccessIterator last) {
  618.     __stl_debug_check(__check_range(first, last));
  619.     __random_shuffle(first, last, distance_type(first));
  620. }
  621.  
  622. template <class RandomAccessIterator, class RandomNumberGenerator>
  623. void random_shuffle(RandomAccessIterator first, RandomAccessIterator last,
  624.                     RandomNumberGenerator& rand) {
  625.     __stl_debug_check(__check_range(first, last));
  626.     if (first == last) return;
  627.     for (RandomAccessIterator i = first + 1; i != last; ++i)
  628.         iter_swap(i, first + rand((i - first) + 1));
  629. }
  630.  
  631. template <class ForwardIterator, class OutputIterator, class Distance>
  632. OutputIterator random_sample_n(ForwardIterator first, ForwardIterator last,
  633.                                OutputIterator out, const Distance n)
  634. {
  635.     __stl_debug_check(__check_range(first, last));
  636.     Distance remaining = 0;
  637.     distance(first, last, remaining);
  638.     Distance m = min(n, remaining);
  639.  
  640.     while (m > 0) {
  641.         if (__rand() % remaining < m) {
  642.             *out = *first;
  643.             ++out;
  644.             --m;
  645.         }
  646.  
  647.         --remaining;
  648.         ++first;
  649.     }
  650.     return out;
  651. }
  652.  
  653. template <class ForwardIterator, class OutputIterator, class Distance,
  654.     class RandomNumberGenerator>
  655. OutputIterator random_sample_n(ForwardIterator first, ForwardIterator last,
  656.                                OutputIterator out, const Distance n,
  657.                                RandomNumberGenerator& rand)
  658. {
  659.     __stl_debug_check(__check_range(first, last));
  660.     Distance remaining = 0;
  661.     distance(first, last, remaining);
  662.     Distance m = min(n, remaining);
  663.  
  664.     while (m > 0) {
  665.         if (rand(remaining) < m) {
  666.             *out = *first;
  667.             --m;
  668.             ++out;
  669.         }
  670.  
  671.         --remaining;
  672.         ++first;
  673.     }
  674.     return out;
  675. }
  676.  
  677. template <class InputIterator, class RandomAccessIterator, class Distance>
  678. RandomAccessIterator __random_sample(InputIterator first, InputIterator last,
  679.                                      RandomAccessIterator out,
  680.                                      const Distance n)
  681. {
  682.     Distance m = 0;
  683.     Distance t = n;
  684.     for (; first != last && m < n; ++m,++first) 
  685.         out[m] = *first;
  686.  
  687.     while (first != last) {
  688.         ++t;
  689.         Distance M = __rand() % t;
  690.         if (M < n)
  691.             out[M] = *first;
  692.         ++first;
  693.     }
  694.  
  695.     return out + m;
  696. }
  697.  
  698. template <class InputIterator, class RandomAccessIterator,
  699.     class RandomNumberGenerator, class Distance>
  700. RandomAccessIterator __random_sample(InputIterator first, InputIterator last,
  701.                                      RandomAccessIterator out,
  702.                                      RandomNumberGenerator& rand,
  703.                                      const Distance n)
  704. {
  705.     Distance m = 0;
  706.     Distance t = n;
  707.     for (; first != last && m < n; ++m,++first) 
  708.         out[m] = *first;
  709.  
  710.     while (first != last) {
  711.         ++t;
  712.         Distance M = rand(t);
  713.         if (M < n)
  714.             out[M] = *first;
  715.         ++first;
  716.     }
  717.  
  718.     return out + m;
  719. }
  720.  
  721. template <class InputIterator, class RandomAccessIterator>
  722. inline RandomAccessIterator
  723. random_sample(InputIterator first, InputIterator last,
  724.               RandomAccessIterator out_first, RandomAccessIterator out_last) 
  725. {
  726.     __stl_debug_check(__check_range(first, last));
  727.     return __random_sample(first, last, out_first, out_last - out_first);
  728. }
  729.  
  730. template <class InputIterator, class RandomAccessIterator, 
  731.     class RandomNumberGenerator>
  732. inline RandomAccessIterator
  733. random_sample(InputIterator first, InputIterator last,
  734.               RandomAccessIterator out_first, RandomAccessIterator out_last,
  735.               RandomNumberGenerator& rand) 
  736. {
  737.     __stl_debug_check(__check_range(first, last));
  738.     return __random_sample(first, last, out_first, rand, out_last - out_first);
  739. }
  740.  
  741. template <class BidirectionalIterator, class Predicate>
  742. BidirectionalIterator partition(BidirectionalIterator first,
  743.                                 BidirectionalIterator last, Predicate pred) {
  744.     __stl_debug_check(__check_range(first, last));
  745.     while (true) {
  746.         while (true)
  747.             if (first == last)
  748.                 return first;
  749.             else if (pred(*first))
  750.                 ++first;
  751.             else
  752.                 break;
  753.         --last;
  754.         while (true)
  755.             if (first == last)
  756.                 return first;
  757.             else if (!pred(*last))
  758.                 --last;
  759.             else
  760.                 break;
  761.         iter_swap(first, last);
  762.         ++first;
  763.     }
  764. }
  765.  
  766. template <class ForwardIterator, class Predicate, class Distance>
  767. ForwardIterator __inplace_stable_partition(ForwardIterator first,
  768.                                            ForwardIterator last,
  769.                                            Predicate pred, Distance len) {
  770.     if (len == 1) return pred(*first) ? last : first;
  771.     ForwardIterator middle = first;
  772.     advance(middle, len / 2);
  773.     ForwardIterator 
  774.         first_cut = __inplace_stable_partition(first, middle, pred, len / 2);
  775.     ForwardIterator 
  776.         second_cut = __inplace_stable_partition(middle, last, pred,
  777.                                                 len - len / 2);
  778.     rotate(first_cut, middle, second_cut);
  779.     len = 0;
  780.     distance(middle, second_cut, len);
  781.     advance(first_cut, len);
  782.     return first_cut;
  783. }
  784.  
  785. template <class ForwardIterator, class Predicate, class Distance, class T>
  786. ForwardIterator __stable_partition_adaptive(ForwardIterator first,
  787.                                             ForwardIterator last,
  788.                                             Predicate pred, Distance len,
  789.                                             __stl_tempbuf<T,Distance>& buffer) {
  790.     typedef typename  __stl_tempbuf<T,Distance>::pointer Pointer;
  791.     Distance fill_pointer = buffer.size();
  792.     if (len <= buffer.capacity()) {
  793.         len = 0;
  794.         ForwardIterator result1 = first;
  795.         Pointer result2 = buffer.begin();
  796.         for (; first != last && len < fill_pointer; ++first)
  797.             if (pred(*first)) {
  798.                 *result1 = *first;
  799.                 ++result1;
  800.             }
  801.             else {
  802.                 *result2++ = *first;
  803.                 ++len;
  804.             }
  805.         if (first != last) {
  806.             raw_storage_iterator<Pointer, T> result3(result2);
  807.             __TRY {
  808.                 for (; first != last; ++first)              
  809.                     if (pred(*first)) {
  810.                         *result1 = *first;
  811.                         ++result1;
  812.                     }
  813.                     else {
  814.                         *result3 = *first;
  815.                         ++len;
  816.                         ++result3;
  817.                     }
  818.             }
  819. #  if defined ( __STL_USE_EXCEPTIONS )
  820.             catch(...) {
  821.                 buffer.adjust_size(len);
  822.                 throw;
  823.             }
  824. #  endif
  825.             buffer.adjust_size(len);
  826.         }
  827.         copy(buffer.begin(), buffer.begin() + len, result1);
  828.         return result1;
  829.     }
  830.     ForwardIterator middle = first;
  831.     advance(middle, len / 2);
  832.     ForwardIterator first_cut = __stable_partition_adaptive
  833.         (first, middle, pred, len / 2, buffer); 
  834.     ForwardIterator second_cut = __stable_partition_adaptive
  835.         (middle, last, pred, len - len / 2, buffer); 
  836.     rotate(first_cut, middle, second_cut);
  837.     len = 0;
  838.     distance(middle, second_cut, len);
  839.     advance(first_cut, len);
  840.     return first_cut;
  841. }
  842.  
  843. template <class ForwardIterator, class Predicate, class T,
  844.                                                 class Distance>
  845. ForwardIterator __stable_partition(ForwardIterator first, ForwardIterator last,
  846.                                    Predicate pred, Distance len,
  847.                                    __stl_tempbuf<T, Distance>& buffer) {
  848.     if ( buffer.capacity() >0 )
  849.        return __stable_partition_adaptive(first, last, pred, len, buffer);
  850.     else
  851.        return __inplace_stable_partition(first, last, pred, len);
  852. }
  853.  
  854. template <class ForwardIterator, class Predicate, class Distance, class T>
  855. inline ForwardIterator __stable_partition_aux(ForwardIterator first,
  856.                                               ForwardIterator last, 
  857.                                               Predicate pred, Distance*, T*) {
  858.     Distance len = 0;
  859.     distance(first, last, len);
  860.     __stl_tempbuf<T,Distance> buf(len);
  861.     return __stable_partition(first, last, pred, len, buf);
  862. }
  863.  
  864. template <class ForwardIterator, class Predicate>
  865. inline ForwardIterator stable_partition(ForwardIterator first,
  866.                                         ForwardIterator last, 
  867.                                         Predicate pred) {
  868.     __stl_debug_check(__check_range(first, last));
  869.     return __stable_partition_aux(first, last, pred, distance_type(first),value_type(first));
  870. }
  871.  
  872. template <class RandomAccessIterator, class T>
  873. RandomAccessIterator __unguarded_partition(RandomAccessIterator first, 
  874.                                            RandomAccessIterator last, 
  875.                                            T pivot) {
  876.     while (1) {
  877.         while (*first < pivot) {
  878.             ++first;
  879.         }
  880.         --last;
  881.         while (pivot < *last) --last;
  882.         if (!(first < last)) { 
  883.             return first;
  884.         }
  885.         iter_swap(first, last);
  886.         ++first;
  887.     }
  888. }    
  889.  
  890. template <class RandomAccessIterator, class T, class Compare>
  891. RandomAccessIterator __unguarded_partition(RandomAccessIterator first, 
  892.                                            RandomAccessIterator last, 
  893.                                            T pivot, Compare comp) {
  894.     while (1) {
  895.         while (comp(*first, pivot)) ++first;
  896.         --last;
  897.         while (comp(pivot, *last)) --last;
  898.         if (!(first < last)) return first;
  899.         iter_swap(first, last);
  900.         ++first;
  901.     }
  902. }
  903.  
  904. # define  __stl_threshold  16
  905.  
  906. template <class RandomAccessIterator, class T>
  907. void __unguarded_linear_insert(RandomAccessIterator last, T value) {
  908.     RandomAccessIterator next = last;
  909.     --next;
  910.     while (value < *next) {
  911.         *last = *next;
  912.         last = next;
  913.         --next;
  914.     }
  915.     *last = value;
  916. }
  917.  
  918. template <class RandomAccessIterator, class T, class Compare>
  919. void __unguarded_linear_insert(RandomAccessIterator last, T value, 
  920.                                Compare comp) {
  921.     RandomAccessIterator next = last;
  922.     --next;  
  923.     while (comp(value , *next)) {
  924.         *last = *next;
  925.         last = next;
  926.         --next;
  927.     }
  928.     *last = value;
  929. }
  930.  
  931. template <class RandomAccessIterator, class T>
  932. inline void __linear_insert(RandomAccessIterator first, 
  933.                             RandomAccessIterator last, T*) {
  934.     T value = *last;
  935.     if (value < *first) {
  936.         copy_backward(first, last, last + 1);
  937.         *first = value;
  938.     } else
  939.         __unguarded_linear_insert(last, value);
  940. }
  941.  
  942. template <class RandomAccessIterator, class T, class Compare>
  943. inline void __linear_insert(RandomAccessIterator first, 
  944.                             RandomAccessIterator last, T*, Compare comp) {
  945.     T value = *last;
  946.     if (comp(value, *first)) {
  947.         copy_backward(first, last, last + 1);
  948.         *first = value;
  949.     } else
  950.         __unguarded_linear_insert(last, value, comp);
  951. }
  952.  
  953. template <class RandomAccessIterator>
  954. void __insertion_sort(RandomAccessIterator first, RandomAccessIterator last) {
  955.     if (first == last) return; 
  956.     for (RandomAccessIterator i = first + 1; i != last; ++i)
  957.         __linear_insert(first, i, value_type(first));
  958. }
  959.  
  960. template <class RandomAccessIterator, class Compare>
  961. void __insertion_sort(RandomAccessIterator first,
  962.                       RandomAccessIterator last, Compare comp) {
  963.     if (first == last) return;
  964.     for (RandomAccessIterator i = first + 1; i != last; ++i)
  965.         __linear_insert(first, i, value_type(first), comp);
  966. }
  967.  
  968. template <class RandomAccessIterator, class T>
  969. void __unguarded_insertion_sort_aux(RandomAccessIterator first, 
  970.                                     RandomAccessIterator last, T*) {
  971.     for (RandomAccessIterator i = first; i != last; ++i)
  972.         __unguarded_linear_insert(i, T(*i));
  973. }
  974.  
  975. template <class RandomAccessIterator>
  976. inline void __unguarded_insertion_sort(RandomAccessIterator first, 
  977.                                        RandomAccessIterator last) {
  978.     __unguarded_insertion_sort_aux(first, last, value_type(first));
  979. }
  980.  
  981. template <class RandomAccessIterator, class T, class Compare>
  982. void __unguarded_insertion_sort_aux(RandomAccessIterator first, 
  983.                                     RandomAccessIterator last,
  984.                                     T*, Compare comp) {
  985.     for (RandomAccessIterator i = first; i != last; ++i)
  986.         __unguarded_linear_insert(i, T(*i), comp);
  987. }
  988.  
  989. template <class RandomAccessIterator, class Compare>
  990. inline void __unguarded_insertion_sort(RandomAccessIterator first, 
  991.                                        RandomAccessIterator last,
  992.                                        Compare comp) {
  993.     __unguarded_insertion_sort_aux(first, last, value_type(first), comp);
  994. }
  995.  
  996. template <class RandomAccessIterator>
  997. void __final_insertion_sort(RandomAccessIterator first, 
  998.                             RandomAccessIterator last) {
  999.     if (last - first > __stl_threshold) {
  1000.         __insertion_sort(first, first + __stl_threshold);
  1001.         __unguarded_insertion_sort(first + __stl_threshold, last);
  1002.     } else
  1003.         __insertion_sort(first, last);
  1004. }
  1005.  
  1006. template <class RandomAccessIterator, class Compare>
  1007. void __final_insertion_sort(RandomAccessIterator first, 
  1008.                             RandomAccessIterator last, Compare comp) {
  1009.     if (last - first > __stl_threshold) {
  1010.         __insertion_sort(first, first + __stl_threshold, comp);
  1011.         __unguarded_insertion_sort(first + __stl_threshold, last, comp);
  1012.     } else
  1013.         __insertion_sort(first, last, comp);
  1014. }
  1015.  
  1016. template <class Size>
  1017. Size __lg(Size n) {
  1018.     Size k;
  1019.     for (k = 0; n != 1; n = n / 2) ++k;
  1020.     return k;
  1021. }
  1022.  
  1023. template <class RandomAccessIterator, class T, class Size>
  1024. void __introsort_loop(RandomAccessIterator first,
  1025.                       RandomAccessIterator last, T*,
  1026.                       Size depth_limit) {
  1027.     while (last - first > __stl_threshold) {
  1028.         if (depth_limit == 0) {
  1029.             partial_sort(first, last, last);
  1030.             return;
  1031.         }
  1032.         --depth_limit;
  1033.         RandomAccessIterator cut = __unguarded_partition
  1034.             (first, last, T(__median(*first, *(first + (last - first)/2),
  1035.                                      *(last - 1))));
  1036.         __introsort_loop(cut, last, value_type(first), depth_limit);
  1037.         last = cut;
  1038.     }
  1039. }
  1040.  
  1041. template <class RandomAccessIterator, class T, class Size, class Compare>
  1042. void __introsort_loop(RandomAccessIterator first,
  1043.                       RandomAccessIterator last, T*,
  1044.                       Size depth_limit, Compare comp) {
  1045.     while (last - first > __stl_threshold) {
  1046.         if (depth_limit == 0) {
  1047.             partial_sort(first, last, last, comp);
  1048.             return;
  1049.         }
  1050.         --depth_limit;
  1051.         RandomAccessIterator cut = __unguarded_partition
  1052.             (first, last, T(__median(*first, *(first + (last - first)/2),
  1053.                                      *(last - 1), comp)), comp);
  1054.         __introsort_loop(cut, last, value_type(first), depth_limit, comp);
  1055.         last = cut;
  1056.     }
  1057. }
  1058.  
  1059. template <class RandomAccessIterator>
  1060. inline void sort(RandomAccessIterator first, RandomAccessIterator last) {
  1061.     __stl_debug_check(__check_range(first, last));
  1062.     if (first==last) return;
  1063.     __introsort_loop(first, last, value_type(first), __lg(last - first) * 2);
  1064.     __final_insertion_sort(first, last);
  1065. }
  1066.  
  1067. template <class RandomAccessIterator, class Compare>
  1068. inline void sort(RandomAccessIterator first, RandomAccessIterator last,
  1069.                  Compare comp) {
  1070.     __stl_debug_check(__check_range(first, last));
  1071.     if (first == last) return;
  1072.     __introsort_loop(first, last, value_type(first), __lg(last - first) * 2,
  1073.                      comp);
  1074.     __final_insertion_sort(first, last, comp);
  1075. }
  1076.  
  1077.  
  1078. template <class RandomAccessIterator>
  1079. void __inplace_stable_sort(RandomAccessIterator first,
  1080.                            RandomAccessIterator last) {
  1081.     if (last - first < 15) {
  1082.         __insertion_sort(first, last);
  1083.         return;
  1084.     }
  1085.     RandomAccessIterator middle = first + (last - first) / 2;
  1086.     __inplace_stable_sort(first, middle);
  1087.     __inplace_stable_sort(middle, last);
  1088.     __merge_without_buffer(first, middle, last, middle - first, last - middle);
  1089. }
  1090.  
  1091. template <class RandomAccessIterator, class Compare>
  1092. void __inplace_stable_sort(RandomAccessIterator first,
  1093.                            RandomAccessIterator last, Compare comp) {
  1094.     if (last - first < 15) {
  1095.         __insertion_sort(first, last, comp);
  1096.         return;
  1097.     }
  1098.     RandomAccessIterator middle = first + (last - first) / 2;
  1099.     __inplace_stable_sort(first, middle, comp);
  1100.     __inplace_stable_sort(middle, last, comp);
  1101.     __merge_without_buffer(first, middle, last, middle - first,
  1102.                            last - middle, comp);
  1103. }
  1104.  
  1105. template <class RandomAccessIterator1, class RandomAccessIterator2,
  1106.                                class Distance>
  1107. void __merge_sort_loop(RandomAccessIterator1 first,
  1108.                        RandomAccessIterator1 last, 
  1109.                        RandomAccessIterator2 result, Distance step_size) {
  1110.     Distance two_step = 2 * step_size;
  1111.  
  1112.     while (last - first >= two_step) {
  1113.         result = merge(first, first + step_size,
  1114.                        first + step_size, first + two_step, result);
  1115.         first += two_step;
  1116.     }
  1117.     Distance len(last-first); // VC++ temporary ref warning
  1118.     step_size = min(len, step_size);
  1119.     merge(first, first + step_size, first + step_size, last, result);
  1120. }
  1121.  
  1122. template <class RandomAccessIterator1, class RandomAccessIterator2,
  1123.                            class Distance, class Compare>
  1124. void __merge_sort_loop(RandomAccessIterator1 first,
  1125.                        RandomAccessIterator1 last, 
  1126.                        RandomAccessIterator2 result, Distance step_size,
  1127.                        Compare comp) {
  1128.     Distance two_step = 2 * step_size;
  1129.  
  1130.     while (last - first >= two_step) {
  1131.         result = merge(first, first + step_size,
  1132.                        first + step_size, first + two_step, result, comp);
  1133.         first += two_step;
  1134.     }
  1135.     Distance len(last-first); // VC++ temporary ref warning
  1136.     step_size = min(len, step_size);
  1137.  
  1138.     merge(first, first + step_size, first + step_size, last, result, comp);
  1139. }
  1140.  
  1141. const int __stl_chunk_size = 7;
  1142.         
  1143. template <class RandomAccessIterator, class Distance>
  1144. void __chunk_insertion_sort(RandomAccessIterator first, 
  1145.                             RandomAccessIterator last, Distance chunk_size) {
  1146.     while (last - first >= chunk_size) {
  1147.         __insertion_sort(first, first + chunk_size);
  1148.         first += chunk_size;
  1149.     }
  1150.     __insertion_sort(first, last);
  1151. }
  1152.  
  1153. template <class RandomAccessIterator, class Distance, class Compare>
  1154. void __chunk_insertion_sort(RandomAccessIterator first, 
  1155.                             RandomAccessIterator last,
  1156.                             Distance chunk_size, Compare comp) {
  1157.     while (last - first >= chunk_size) {
  1158.         __insertion_sort(first, first + chunk_size, comp);
  1159.         first += chunk_size;
  1160.     }
  1161.     __insertion_sort(first, last, comp);
  1162. }
  1163.  
  1164. template <class RandomAccessIterator, class Distance, class T>
  1165. void __merge_sort_with_buffer(RandomAccessIterator first, 
  1166.                               RandomAccessIterator last, 
  1167.                               __stl_tempbuf<T, Distance>& buffer) {   
  1168.     typedef typename  __stl_tempbuf<T,Distance>::pointer Pointer;
  1169.     Distance len = last - first;
  1170.     Pointer buffer_last = buffer.begin() + len;
  1171.  
  1172.     Distance step_size = __stl_chunk_size;
  1173.     __chunk_insertion_sort(first, last, step_size);
  1174.  
  1175.     while (step_size < len) {
  1176.         __merge_sort_loop(first, last, buffer.begin(), step_size);
  1177.         step_size *= 2;
  1178.         __merge_sort_loop(buffer.begin(), buffer_last, first, step_size);
  1179.         step_size *= 2;
  1180.     }
  1181. }
  1182.  
  1183.  
  1184. template <class RandomAccessIterator, class Distance, class T,
  1185.                                   class Compare>
  1186. void __merge_sort_with_buffer(RandomAccessIterator first, 
  1187.                               RandomAccessIterator last, 
  1188.                               __stl_tempbuf<T, Distance>& buffer,
  1189.                               Compare comp) {   
  1190.     typedef typename  __stl_tempbuf<T,Distance>::pointer Pointer;
  1191.     Distance len = last - first;
  1192.     Pointer buffer_last = buffer.begin() + len;
  1193.  
  1194.     Distance step_size = __stl_chunk_size;
  1195.     __chunk_insertion_sort(first, last, step_size, comp);
  1196.  
  1197.     while (step_size < len) {
  1198.         __merge_sort_loop(first, last, buffer.begin(), step_size, comp);
  1199.         step_size *= 2;
  1200.         __merge_sort_loop(buffer.begin(), buffer_last, first, step_size, comp);
  1201.         step_size *= 2;
  1202.     }
  1203. }
  1204.  
  1205. template <class RandomAccessIterator, class Distance, class T>
  1206. void __stable_sort_adaptive(RandomAccessIterator first, 
  1207.                             RandomAccessIterator last, 
  1208.                             __stl_tempbuf<T,Distance>& buffer) {
  1209.     Distance len = (last - first + 1) / 2;
  1210.     RandomAccessIterator middle = first + len;
  1211.     if (len > buffer.capacity()) {
  1212.         __stable_sort_adaptive(first, middle, buffer);
  1213.         __stable_sort_adaptive(middle, last, buffer);
  1214.     } else {
  1215.     __merge_sort_with_buffer(first, middle, buffer);
  1216.     __merge_sort_with_buffer(middle, last, buffer);
  1217.     }
  1218.     __merge_adaptive(first, middle, last, Distance(middle - first), 
  1219.                      Distance(last - middle), buffer);
  1220. }
  1221.  
  1222. template <class RandomAccessIterator, class Distance, class T,
  1223.                                 class Compare>
  1224. void __stable_sort_adaptive(RandomAccessIterator first, 
  1225.                             RandomAccessIterator last, 
  1226.                             __stl_tempbuf<T,Distance>& buffer,
  1227.                             Compare comp) {
  1228.     Distance len = (last - first + 1) / 2;
  1229.     RandomAccessIterator middle = first + len;
  1230.     if (len > buffer.capacity()) {
  1231.         __stable_sort_adaptive(first, middle, buffer, comp);
  1232.         __stable_sort_adaptive(middle, last, buffer, comp);
  1233.     } else {
  1234.         __merge_sort_with_buffer(first, middle, buffer, comp);
  1235.         __merge_sort_with_buffer(middle, last, buffer, comp);
  1236.     }
  1237.     __merge_adaptive(first, middle, last, Distance(middle - first), 
  1238.                      Distance(last - middle), buffer, comp);
  1239. }
  1240.  
  1241. template <class RandomAccessIterator, class Distance, class T>
  1242. inline void __stable_sort(RandomAccessIterator first,
  1243.                           RandomAccessIterator last,
  1244.                           __stl_tempbuf<T,Distance>& buffer) {
  1245.     if (buffer.capacity() == 0) {
  1246.         __inplace_stable_sort(first, last);
  1247.     }
  1248.     else {
  1249.         Distance len(last-first); // VC++ temporary ref warning
  1250.         len = min(buffer.capacity(), len);
  1251.         uninitialized_copy(first, first + len, buffer.begin());
  1252.         buffer.adjust_size(len);
  1253.         __stable_sort_adaptive(first, last, buffer);
  1254.     }
  1255. }
  1256.  
  1257. template <class RandomAccessIterator, class Distance, class T,
  1258.                               class Compare>
  1259. inline void __stable_sort(RandomAccessIterator first,
  1260.                           RandomAccessIterator last,
  1261.                           __stl_tempbuf<T,Distance>& buffer, Compare comp) {
  1262.     if (buffer.capacity() == 0) {
  1263.         __inplace_stable_sort(first, last, comp);
  1264.     }
  1265.     else {
  1266.         Distance len(last-first); // VC++ temporary ref warning
  1267.         len = min(buffer.capacity(), len);
  1268.         uninitialized_copy(first, first + len, buffer.begin());
  1269.         buffer.adjust_size(len);
  1270.         __stable_sort_adaptive(first, last, buffer, comp);
  1271.     }
  1272. }
  1273.  
  1274. template <class RandomAccessIterator, class T, class Distance>
  1275. inline void __stable_sort_aux(RandomAccessIterator first,
  1276.                               RandomAccessIterator last, T*, Distance*) {
  1277.     __stl_tempbuf<T,Distance> buffer(Distance(last - first));
  1278.     __stable_sort(first, last, buffer);
  1279. }
  1280.  
  1281. template <class RandomAccessIterator, class T, class Distance, class Compare>
  1282. inline void __stable_sort_aux(RandomAccessIterator first,
  1283.                               RandomAccessIterator last, T*, Distance*,
  1284.                               Compare comp) {
  1285.     __stl_tempbuf<T,Distance> buffer(Distance(last - first));
  1286.     __stable_sort(first, last, buffer,comp);
  1287. }
  1288.  
  1289. template <class RandomAccessIterator>
  1290. inline void stable_sort(RandomAccessIterator first,
  1291.                         RandomAccessIterator last) {
  1292.     __stl_debug_check(__check_range(first, last));
  1293.     __stable_sort_aux(first, last, value_type(first), distance_type(first));
  1294. }
  1295.  
  1296. template <class RandomAccessIterator, class Compare>
  1297. inline void stable_sort(RandomAccessIterator first,
  1298.                         RandomAccessIterator last, Compare comp) {
  1299.     __stl_debug_check(__check_range(first, last));
  1300.     __stable_sort_aux(first, last, value_type(first), distance_type(first), 
  1301.                       comp);
  1302. }
  1303.  
  1304. template <class RandomAccessIterator, class T>
  1305. void __partial_sort(RandomAccessIterator first, RandomAccessIterator middle,
  1306.                     RandomAccessIterator last, T*) {
  1307.     make_heap(first, middle);
  1308.     for (RandomAccessIterator i = middle; i < last; ++i)
  1309.         if (*i < *first) 
  1310.             __pop_heap(first, middle, i, T(*i), distance_type(first));
  1311.     sort_heap(first, middle);
  1312. }
  1313.  
  1314. template <class RandomAccessIterator>
  1315. inline void partial_sort(RandomAccessIterator first,
  1316.                          RandomAccessIterator middle,
  1317.                          RandomAccessIterator last) {
  1318.     __stl_debug_check(__check_range(middle,first, last));
  1319.     __partial_sort(first, middle, last, value_type(first));
  1320. }
  1321.  
  1322. template <class RandomAccessIterator, class T, class Compare>
  1323. void __partial_sort(RandomAccessIterator first, RandomAccessIterator middle,
  1324.                     RandomAccessIterator last, T*, Compare comp) {
  1325.     make_heap(first, middle, comp);
  1326.     for (RandomAccessIterator i = middle; i < last; ++i)
  1327.         if (comp(*i, *first))
  1328.             __pop_heap(first, middle, i, T(*i), comp, distance_type(first));
  1329.     sort_heap(first, middle, comp);
  1330. }
  1331.  
  1332. template <class RandomAccessIterator, class Compare>
  1333. inline void partial_sort(RandomAccessIterator first,
  1334.                          RandomAccessIterator middle,
  1335.                          RandomAccessIterator last, Compare comp) {
  1336.     __stl_debug_check(__check_range(middle,first, last));
  1337.     __partial_sort(first, middle, last, value_type(first), comp);
  1338. }
  1339.  
  1340. template <class InputIterator, class RandomAccessIterator, class Distance,
  1341.                              class T>
  1342. RandomAccessIterator __partial_sort_copy(InputIterator first,
  1343.                                          InputIterator last,
  1344.                                          RandomAccessIterator result_first,
  1345.                                          RandomAccessIterator result_last, 
  1346.                                          Distance*, T*) {
  1347.     if (result_first == result_last) return result_last;
  1348.     RandomAccessIterator result_real_last = result_first;
  1349.     for (; first != last && result_real_last != result_last; ++result_real_last,++first)
  1350.         *result_real_last = *first;
  1351.     make_heap(result_first, result_real_last);
  1352.     while (first != last) {
  1353.         if (*first < *result_first) 
  1354.             __adjust_heap(result_first, Distance(0),
  1355.                           Distance(result_real_last - result_first), T(*first));
  1356.         ++first;
  1357.     }
  1358.     sort_heap(result_first, result_real_last);
  1359.     return result_real_last;
  1360. }
  1361.  
  1362. template <class InputIterator, class RandomAccessIterator>
  1363. inline RandomAccessIterator
  1364. partial_sort_copy(InputIterator first, InputIterator last,
  1365.                   RandomAccessIterator result_first,
  1366.                   RandomAccessIterator result_last) {
  1367.     __stl_debug_check(__check_range(first, last));
  1368.     __stl_debug_check(__check_range(result_first, result_last));
  1369.     return __partial_sort_copy(first, last, result_first, result_last, 
  1370.                                distance_type(result_first), value_type(first));
  1371. }
  1372.  
  1373. template <class InputIterator, class RandomAccessIterator, class Compare,
  1374.                       class Distance, class T>
  1375. RandomAccessIterator __partial_sort_copy(InputIterator first,
  1376.                                          InputIterator last,
  1377.                                          RandomAccessIterator result_first,
  1378.                                          RandomAccessIterator result_last,
  1379.                                          Compare comp, Distance*, T*) {
  1380.     if (result_first == result_last) return result_last;
  1381.     RandomAccessIterator result_real_last = result_first;
  1382.     for (; first != last && result_real_last != result_last; ++result_real_last,++first)
  1383.         *result_real_last = *first;
  1384.     make_heap(result_first, result_real_last, comp);
  1385.     while (first != last) {
  1386.         if (comp(*first, *result_first))
  1387.             __adjust_heap(result_first, Distance(0),
  1388.                           Distance(result_real_last - result_first), T(*first),
  1389.                           comp);
  1390.         ++first;
  1391.     }
  1392.     sort_heap(result_first, result_real_last, comp);
  1393.     return result_real_last;
  1394. }
  1395.  
  1396. template <class InputIterator, class RandomAccessIterator, class Compare>
  1397. inline RandomAccessIterator
  1398. partial_sort_copy(InputIterator first, InputIterator last,
  1399.                   RandomAccessIterator result_first,
  1400.                   RandomAccessIterator result_last, Compare comp) {
  1401.     __stl_debug_check(__check_range(first, last));
  1402.     __stl_debug_check(__check_range(result_first, result_last));
  1403.     return __partial_sort_copy(first, last, result_first, result_last, comp,
  1404.                                distance_type(result_first), value_type(first));
  1405. }
  1406.  
  1407. template <class RandomAccessIterator, class T>
  1408. void __nth_element(RandomAccessIterator first, RandomAccessIterator nth,
  1409.                    RandomAccessIterator last, T*) {
  1410.     while (last - first > 3) {
  1411.         RandomAccessIterator cut = __unguarded_partition
  1412.             (first, last, T(__median(*first, *(first + (last - first)/2),
  1413.                                      *(last - 1))));
  1414.         if (cut <= nth)
  1415.             first = cut;
  1416.         else 
  1417.             last = cut;
  1418.     }
  1419.     __insertion_sort(first, last);
  1420. }
  1421.  
  1422. template <class RandomAccessIterator>
  1423. inline void nth_element(RandomAccessIterator first, RandomAccessIterator nth,
  1424.                         RandomAccessIterator last) {
  1425.     __stl_debug_check(__check_range(nth,first, last));
  1426.     __nth_element(first, nth, last, value_type(first));
  1427. }
  1428.  
  1429. template <class RandomAccessIterator, class T, class Compare>
  1430. void __nth_element(RandomAccessIterator first, RandomAccessIterator nth,
  1431.                    RandomAccessIterator last, T*, Compare comp) {
  1432.     while (last - first > 3) {
  1433.         RandomAccessIterator cut = __unguarded_partition
  1434.             (first, last, T(__median(*first, *(first + (last - first)/2), 
  1435.                                      *(last - 1), comp)), comp);
  1436.         if (cut <= nth)
  1437.             first = cut;
  1438.         else 
  1439.             last = cut;
  1440.     }
  1441.     __insertion_sort(first, last, comp);
  1442. }
  1443.  
  1444. template <class RandomAccessIterator, class Compare>
  1445. inline void nth_element(RandomAccessIterator first, RandomAccessIterator nth,
  1446.                         RandomAccessIterator last, Compare comp) {
  1447.     __stl_debug_check(__check_range(nth, first, last));
  1448.     __nth_element(first, nth, last, value_type(first), comp);
  1449. }
  1450.  
  1451. template <class ForwardIterator, class T, class Distance>
  1452. ForwardIterator __lower_bound(ForwardIterator first, ForwardIterator last,
  1453.                               const T& value, Distance*,
  1454.                               forward_iterator_tag) {
  1455.     Distance len = 0;
  1456.     distance(first, last, len);
  1457.     Distance half;
  1458.     ForwardIterator middle;
  1459.  
  1460.     while (len > 0) {
  1461.         half = len / 2;
  1462.         middle = first;
  1463.         advance(middle, half);
  1464.         if (*middle < value) {
  1465.             first = middle;
  1466.             ++first;
  1467.             len = len - half - 1;
  1468.         } else
  1469.             len = half;
  1470.     }
  1471.     return first;
  1472. }
  1473.  
  1474. template <class ForwardIterator, class T, class Distance>
  1475. inline ForwardIterator __lower_bound(ForwardIterator first,
  1476.                                      ForwardIterator last,
  1477.                                      const T& value, Distance*,
  1478.                                      bidirectional_iterator_tag) {
  1479.     return __lower_bound(first, last, value, (Distance*)0,
  1480.                          forward_iterator_tag());
  1481. }
  1482.  
  1483. template <class RandomAccessIterator, class T, class Distance>
  1484. RandomAccessIterator __lower_bound(RandomAccessIterator first,
  1485.                                    RandomAccessIterator last, const T& value,
  1486.                                    Distance*, random_access_iterator_tag) {
  1487.     Distance len = last - first;
  1488.     Distance half;
  1489.     RandomAccessIterator middle;
  1490.  
  1491.     while (len > 0) {
  1492.         half = len / 2;
  1493.         middle = first + half;
  1494.         if (*middle < value) {
  1495.             first = middle + 1;
  1496.             len = len - half - 1;
  1497.         } else
  1498.             len = half;
  1499.     }
  1500.     return first;
  1501. }
  1502.  
  1503. template <class ForwardIterator, class T>
  1504. inline ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last,
  1505.                                    const T& value) {
  1506.     __stl_debug_check(__check_range(first, last));
  1507.     return __lower_bound(first, last, value, distance_type(first),
  1508.                          iterator_category(first));
  1509. }
  1510.  
  1511. template <class ForwardIterator, class T, class Compare, class Distance>
  1512. ForwardIterator __lower_bound(ForwardIterator first, ForwardIterator last,
  1513.                               const T& value, Compare comp, Distance*,
  1514.                               forward_iterator_tag) {
  1515.     Distance len = 0;
  1516.     distance(first, last, len);
  1517.     Distance half;
  1518.     ForwardIterator middle;
  1519.  
  1520.     while (len > 0) {
  1521.         half = len / 2;
  1522.         middle = first;
  1523.         advance(middle, half);
  1524.         if (comp(*middle, value)) {
  1525.             first = middle;
  1526.             ++first;
  1527.             len = len - half - 1;
  1528.         } else
  1529.             len = half;
  1530.     }
  1531.     return first;
  1532. }
  1533.  
  1534. template <class ForwardIterator, class T, class Compare, class Distance>
  1535. inline ForwardIterator __lower_bound(ForwardIterator first,
  1536.                                      ForwardIterator last,
  1537.                                      const T& value, Compare comp, Distance*,
  1538.                                      bidirectional_iterator_tag) {
  1539.     return __lower_bound(first, last, value, comp, (Distance*)0,
  1540.                          forward_iterator_tag());
  1541. }
  1542.  
  1543. template <class RandomAccessIterator, class T, class Compare, class Distance>
  1544. RandomAccessIterator __lower_bound(RandomAccessIterator first,
  1545.                                    RandomAccessIterator last,
  1546.                                    const T& value, Compare comp, Distance*,
  1547.                                    random_access_iterator_tag) {
  1548.     Distance len = last - first;
  1549.     Distance half;
  1550.     RandomAccessIterator middle;
  1551.  
  1552.     while (len > 0) {
  1553.         half = len / 2;
  1554.         middle = first + half;
  1555.         if (comp(*middle, value)) {
  1556.             first = middle + 1;
  1557.             len = len - half - 1;
  1558.         } else
  1559.             len = half;
  1560.     }
  1561.     return first;
  1562. }
  1563.  
  1564. template <class ForwardIterator, class T, class Compare>
  1565. inline ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last,
  1566.                                    const T& value, Compare comp) {
  1567.     __stl_debug_check(__check_range(first, last));
  1568.     return __lower_bound(first, last, value, comp, distance_type(first),
  1569.                          iterator_category(first));
  1570. }
  1571.  
  1572. template <class ForwardIterator, class T, class Distance>
  1573. ForwardIterator __upper_bound(ForwardIterator first, ForwardIterator last,
  1574.                               const T& value, Distance*,
  1575.                               forward_iterator_tag) {
  1576.     Distance len = 0;
  1577.     distance(first, last, len);
  1578.     Distance half;
  1579.     ForwardIterator middle;
  1580.  
  1581.     while (len > 0) {
  1582.         half = len / 2;
  1583.         middle = first;
  1584.         advance(middle, half);
  1585.         if (value < *middle)
  1586.             len = half;
  1587.         else {
  1588.             first = middle;
  1589.             ++first;
  1590.             len = len - half - 1;
  1591.         }
  1592.     }
  1593.     return first;
  1594. }
  1595.  
  1596. template <class ForwardIterator, class T, class Distance>
  1597. inline ForwardIterator __upper_bound(ForwardIterator first,
  1598.                                      ForwardIterator last,
  1599.                                      const T& value, Distance*,
  1600.                                      bidirectional_iterator_tag) {
  1601.     return __upper_bound(first, last, value, (Distance*)0,
  1602.                          forward_iterator_tag());
  1603. }
  1604.  
  1605. template <class RandomAccessIterator, class T, class Distance>
  1606. RandomAccessIterator __upper_bound(RandomAccessIterator first,
  1607.                                    RandomAccessIterator last, const T& value,
  1608.                                    Distance*, random_access_iterator_tag) {
  1609.     Distance len = last - first;
  1610.     Distance half;
  1611.     RandomAccessIterator middle;
  1612.  
  1613.     while (len > 0) {
  1614.         half = len / 2;
  1615.         middle = first + half;
  1616.         if (value < *middle)
  1617.             len = half;
  1618.         else {
  1619.             first = middle + 1;
  1620.             len = len - half - 1;
  1621.         }
  1622.     }
  1623.     return first;
  1624. }
  1625.  
  1626. template <class ForwardIterator, class T>
  1627. inline ForwardIterator upper_bound(ForwardIterator first, ForwardIterator last,
  1628.                                    const T& value) {
  1629.     __stl_debug_check(__check_range(first, last));
  1630.     return __upper_bound(first, last, value, distance_type(first),
  1631.                          iterator_category(first));
  1632. }
  1633.  
  1634. template <class ForwardIterator, class T, class Compare, class Distance>
  1635. ForwardIterator __upper_bound(ForwardIterator first, ForwardIterator last,
  1636.                               const T& value, Compare comp, Distance*,
  1637.                               forward_iterator_tag) {
  1638.     Distance len = 0;
  1639.     distance(first, last, len);
  1640.     Distance half;
  1641.     ForwardIterator middle;
  1642.  
  1643.     while (len > 0) {
  1644.         half = len / 2;
  1645.         middle = first;
  1646.         advance(middle, half);
  1647.         if (comp(value, *middle))
  1648.             len = half;
  1649.         else {
  1650.             first = middle;
  1651.             ++first;
  1652.             len = len - half - 1;
  1653.         }
  1654.     }
  1655.     return first;
  1656. }
  1657.  
  1658. template <class ForwardIterator, class T, class Compare, class Distance>
  1659. inline ForwardIterator __upper_bound(ForwardIterator first,
  1660.                                      ForwardIterator last,
  1661.                                      const T& value, Compare comp, Distance*,
  1662.                                      bidirectional_iterator_tag) {
  1663.     return __upper_bound(first, last, value, comp, (Distance*)0,
  1664.                          forward_iterator_tag());
  1665. }
  1666.  
  1667. template <class RandomAccessIterator, class T, class Compare, class Distance>
  1668. RandomAccessIterator __upper_bound(RandomAccessIterator first,
  1669.                                    RandomAccessIterator last,
  1670.                                    const T& value, Compare comp, Distance*,
  1671.                                    random_access_iterator_tag) {
  1672.     Distance len = last - first;
  1673.     Distance half;
  1674.     RandomAccessIterator middle;
  1675.  
  1676.     while (len > 0) {
  1677.         half = len / 2;
  1678.         middle = first + half;
  1679.         if (comp(value, *middle))
  1680.             len = half;
  1681.         else {
  1682.             first = middle + 1;
  1683.             len = len - half - 1;
  1684.         }
  1685.     }
  1686.     return first;
  1687. }
  1688.  
  1689. template <class ForwardIterator, class T, class Compare>
  1690. inline ForwardIterator upper_bound(ForwardIterator first, ForwardIterator last,
  1691.                                    const T& value, Compare comp) {
  1692.     __stl_debug_check(__check_range(first, last));
  1693.     return __upper_bound(first, last, value, comp, distance_type(first),
  1694.                          iterator_category(first));
  1695. }
  1696.  
  1697. template <class ForwardIterator, class T, class Distance>
  1698. pair<ForwardIterator, ForwardIterator>
  1699. __equal_range(ForwardIterator first, ForwardIterator last, const T& value,
  1700.               Distance*, forward_iterator_tag) {
  1701.     Distance len = 0;
  1702.     distance(first, last, len);
  1703.     Distance half;
  1704.     ForwardIterator middle, left, right;
  1705.  
  1706.     while (len > 0) {
  1707.         half = len / 2;
  1708.         middle = first;
  1709.         advance(middle, half);
  1710.         if (*middle < value) {
  1711.             first = middle;
  1712.             ++first;
  1713.             len = len - half - 1;
  1714.         } else if (value < *middle)
  1715.             len = half;
  1716.         else {
  1717.             left = lower_bound(first, middle, value);
  1718.             advance(first, len);
  1719.             right = upper_bound(++middle, first, value);
  1720.             return pair<ForwardIterator, ForwardIterator>(left, right);
  1721.         }
  1722.     }
  1723.     return pair<ForwardIterator, ForwardIterator>(first, first);
  1724. }
  1725.  
  1726. template <class ForwardIterator, class T, class Distance>
  1727. inline pair<ForwardIterator, ForwardIterator>
  1728. __equal_range(ForwardIterator first, ForwardIterator last, const T& value,
  1729.               Distance*, bidirectional_iterator_tag) {
  1730.     return __equal_range(first, last, value, (Distance*)0, 
  1731.                          forward_iterator_tag());
  1732. }
  1733.  
  1734. template <class RandomAccessIterator, class T, class Distance>
  1735. pair<RandomAccessIterator, RandomAccessIterator>
  1736. __equal_range(RandomAccessIterator first, RandomAccessIterator last,
  1737.               const T& value, Distance*, random_access_iterator_tag) {
  1738.     Distance len = last - first;
  1739.     Distance half;
  1740.     RandomAccessIterator middle, left, right;
  1741.  
  1742.     while (len > 0) {
  1743.         half = len / 2;
  1744.         middle = first + half;
  1745.         if (*middle < value) {
  1746.             first = middle + 1;
  1747.             len = len - half - 1;
  1748.         } else if (value < *middle)
  1749.             len = half;
  1750.         else {
  1751.             left = lower_bound(first, middle, value);
  1752.             right = upper_bound(++middle, first + len, value);
  1753.             return pair<RandomAccessIterator, RandomAccessIterator>(left,
  1754.                                                                     right);
  1755.         }
  1756.     }
  1757.     return pair<RandomAccessIterator, RandomAccessIterator>(first, first);
  1758. }
  1759.  
  1760. template <class ForwardIterator, class T>
  1761. inline pair<ForwardIterator, ForwardIterator>
  1762. equal_range(ForwardIterator first, ForwardIterator last, const T& value) {
  1763.     __stl_debug_check(__check_range(first, last));
  1764.     return __equal_range(first, last, value, distance_type(first),
  1765.                          iterator_category(first));
  1766. }
  1767.  
  1768. template <class ForwardIterator, class T, class Compare, class Distance>
  1769. pair<ForwardIterator, ForwardIterator>
  1770. __equal_range(ForwardIterator first, ForwardIterator last, const T& value,
  1771.               Compare comp, Distance*, forward_iterator_tag) {
  1772.     Distance len = 0;
  1773.     distance(first, last, len);
  1774.     Distance half;
  1775.     ForwardIterator middle, left, right;
  1776.  
  1777.     while (len > 0) {
  1778.         half = len / 2;
  1779.         middle = first;
  1780.         advance(middle, half);
  1781.         if (comp(*middle, value)) {
  1782.             first = middle;
  1783.             ++first;
  1784.             len = len - half - 1;
  1785.         } else if (comp(value, *middle))
  1786.             len = half;
  1787.         else {
  1788.             left = lower_bound(first, middle, value, comp);
  1789.             advance(first, len);
  1790.             right = upper_bound(++middle, first, value, comp);
  1791.             return pair<ForwardIterator, ForwardIterator>(left, right);
  1792.         }
  1793.     }
  1794.     return pair<ForwardIterator, ForwardIterator>(first, first);
  1795. }           
  1796.  
  1797. template <class ForwardIterator, class T, class Compare, class Distance>
  1798. inline pair<ForwardIterator, ForwardIterator>
  1799. __equal_range(ForwardIterator first, ForwardIterator last, const T& value,
  1800.               Compare comp, Distance*, bidirectional_iterator_tag) {
  1801.     return __equal_range(first, last, value, comp, (Distance*)0, 
  1802.                          forward_iterator_tag());
  1803. }
  1804.  
  1805. template <class RandomAccessIterator, class T, class Compare, class Distance>
  1806. pair<RandomAccessIterator, RandomAccessIterator>
  1807. __equal_range(RandomAccessIterator first, RandomAccessIterator last,
  1808.               const T& value, Compare comp, Distance*,
  1809.               random_access_iterator_tag) {
  1810.     Distance len = last - first;
  1811.     Distance half;
  1812.     RandomAccessIterator middle, left, right;
  1813.  
  1814.     while (len > 0) {
  1815.         half = len / 2;
  1816.         middle = first + half;
  1817.         if (comp(*middle, value)) {
  1818.             first = middle + 1;
  1819.             len = len - half - 1;
  1820.         } else if (comp(value, *middle))
  1821.             len = half;
  1822.         else {
  1823.             left = lower_bound(first, middle, value, comp);
  1824.             right = upper_bound(++middle, first + len, value, comp);
  1825.             return pair<RandomAccessIterator, RandomAccessIterator>(left,
  1826.                                                                     right);
  1827.         }
  1828.     }
  1829.     return pair<RandomAccessIterator, RandomAccessIterator>(first, first);
  1830. }           
  1831.  
  1832. template <class ForwardIterator, class T, class Compare>
  1833. inline pair<ForwardIterator, ForwardIterator>
  1834. equal_range(ForwardIterator first, ForwardIterator last, const T& value,
  1835.             Compare comp) {
  1836.     __stl_debug_check(__check_range(first, last));
  1837.     return __equal_range(first, last, value, comp, distance_type(first),
  1838.                          iterator_category(first));
  1839. }    
  1840.  
  1841. template <class ForwardIterator, class T>
  1842. bool binary_search(ForwardIterator first, ForwardIterator last,
  1843.                    const T& value) {
  1844.     ForwardIterator i = lower_bound(first, last, value);
  1845.     return i != last && !(value < *i);
  1846. }
  1847.  
  1848. template <class ForwardIterator, class T, class Compare>
  1849. bool binary_search(ForwardIterator first, ForwardIterator last, const T& value,
  1850.                    Compare comp) {
  1851.     ForwardIterator i = lower_bound(first, last, value, comp);
  1852.     return i != last && !comp(value, *i);
  1853. }
  1854.  
  1855. template <class InputIterator1, class InputIterator2, class OutputIterator>
  1856. OutputIterator merge(InputIterator1 first1, InputIterator1 last1,
  1857.                      InputIterator2 first2, InputIterator2 last2,
  1858.                      OutputIterator result) {
  1859.     __stl_debug_check(__check_range(first1, last1));
  1860.     __stl_debug_check(__check_range(first2, last2));
  1861.     for (; first1 != last1 && first2 != last2 ; ++result)
  1862.         if (*first2 < *first1)
  1863.             *result = *first2++;
  1864.         else
  1865.             *result = *first1++;
  1866.     return copy(first2, last2, copy(first1, last1, result));
  1867. }
  1868.  
  1869. template <class InputIterator1, class InputIterator2, class OutputIterator,
  1870.                          class Compare>
  1871. OutputIterator merge(InputIterator1 first1, InputIterator1 last1,
  1872.                      InputIterator2 first2, InputIterator2 last2,
  1873.                      OutputIterator result, Compare comp) {
  1874.     __stl_debug_check(__check_range(first1, last1));
  1875.     __stl_debug_check(__check_range(first2, last2));
  1876.     for (; first1 != last1 && first2 != last2 ; ++result)
  1877.         if (comp(*first2, *first1))
  1878.             *result = *first2++;
  1879.         else
  1880.             *result = *first1++;
  1881.     return copy(first2, last2, copy(first1, last1, result));
  1882. }
  1883.  
  1884. template <class BidirectionalIterator, class Distance>
  1885. void __merge_without_buffer(BidirectionalIterator first,
  1886.                             BidirectionalIterator middle,
  1887.                             BidirectionalIterator last,
  1888.                             Distance len1, Distance len2) {
  1889.     if (len1 == 0 || len2 == 0) return;
  1890.     if (len1 + len2 == 2) {
  1891.         if (*middle < *first) iter_swap(first, middle);
  1892.         return;
  1893.     }
  1894.     BidirectionalIterator first_cut = first;
  1895.     BidirectionalIterator second_cut = middle;
  1896.     Distance len11 = 0;
  1897.     Distance len22 = 0;
  1898.     if (len1 > len2) {
  1899.         len11 = len1 / 2;
  1900.         advance(first_cut, len11);
  1901.         second_cut = lower_bound(middle, last, *first_cut);
  1902.         distance(middle, second_cut, len22);
  1903.     } else {
  1904.         len22 = len2 / 2;
  1905.         advance(second_cut, len22);
  1906.         first_cut = upper_bound(first, middle, *second_cut);
  1907.         distance(first, first_cut, len11);
  1908.     }
  1909.     rotate(first_cut, middle, second_cut);
  1910.     BidirectionalIterator new_middle = first_cut;
  1911.     advance(new_middle, len22);
  1912.     __merge_without_buffer(first, first_cut, new_middle, len11, len22);
  1913.     __merge_without_buffer(new_middle, second_cut, last, len1 - len11,
  1914.                            len2 - len22);
  1915. }
  1916.  
  1917. template <class BidirectionalIterator, class Distance, class Compare>
  1918. void __merge_without_buffer(BidirectionalIterator first,
  1919.                             BidirectionalIterator middle,
  1920.                             BidirectionalIterator last,
  1921.                             Distance len1, Distance len2, Compare comp) {
  1922.     if (len1 == 0 || len2 == 0) return;
  1923.     if (len1 + len2 == 2) {
  1924.         if (comp(*middle, *first)) iter_swap(first, middle);
  1925.         return;
  1926.     }
  1927.     BidirectionalIterator first_cut = first;
  1928.     BidirectionalIterator second_cut = middle;
  1929.     Distance len11 = 0;
  1930.     Distance len22 = 0;
  1931.     if (len1 > len2) {
  1932.         len11 = len1 / 2;
  1933.         advance(first_cut, len11);
  1934.         second_cut = lower_bound(middle, last, *first_cut, comp);
  1935.         distance(middle, second_cut, len22);
  1936.     } else {
  1937.         len22 = len2 / 2;
  1938.         advance(second_cut, len22);
  1939.         first_cut = upper_bound(first, middle, *second_cut, comp);
  1940.         distance(first, first_cut, len11);
  1941.     }
  1942.     rotate(first_cut, middle, second_cut);
  1943.     BidirectionalIterator new_middle = first_cut;
  1944.     advance(new_middle, len22);
  1945.     __merge_without_buffer(first, first_cut, new_middle, len11, len22, comp);
  1946.     __merge_without_buffer(new_middle, second_cut, last, len1 - len11,
  1947.                            len2 - len22, comp);
  1948. }
  1949.  
  1950. template <class BidirectionalIterator1, class BidirectionalIterator2,
  1951.                                 class Distance>
  1952. BidirectionalIterator1 __rotate_adaptive(BidirectionalIterator1 first,
  1953.                                          BidirectionalIterator1 middle,
  1954.                                          BidirectionalIterator1 last,
  1955.                                          Distance len1, Distance len2,
  1956.                                          BidirectionalIterator2 buffer,
  1957.                                          Distance buffer_size) {
  1958.     BidirectionalIterator2 buffer_end;
  1959.     if (len1 > len2 && len2 <= buffer_size) {
  1960.         buffer_end = copy(middle, last, buffer);
  1961.         copy_backward(first, middle, last);
  1962.         return copy(buffer, buffer_end, first);
  1963.     } else if (len1 <= buffer_size) {
  1964.         buffer_end = copy(first, middle, buffer);
  1965.         copy(middle, last, first);
  1966.         return copy_backward(buffer, buffer_end, last);
  1967.     } else  {
  1968.         rotate(first, middle, last);
  1969.         advance(first, len2);
  1970.         return first;
  1971.     }
  1972. }
  1973.  
  1974. template <class BidirectionalIterator1, class BidirectionalIterator2,
  1975.                                              class BidirectionalIterator3>
  1976. BidirectionalIterator3 __merge_backward(BidirectionalIterator1 first1,
  1977.                                         BidirectionalIterator1 last1,
  1978.                                         BidirectionalIterator2 first2,
  1979.                                         BidirectionalIterator2 last2,
  1980.                                         BidirectionalIterator3 result) {
  1981.     if (first1 == last1) return copy_backward(first2, last2, result);
  1982.     if (first2 == last2) return copy_backward(first1, last1, result);
  1983.     --last1;
  1984.     --last2;
  1985.     while (true) {
  1986.         if (*last2 < *last1) {
  1987.             *--result = *last1;
  1988.             if (first1 == last1) return copy_backward(first2, ++last2, result);
  1989.             --last1;
  1990.         } else {
  1991.             *--result = *last2;
  1992.             if (first2 == last2) return copy_backward(first1, ++last1, result);
  1993.             --last2;
  1994.         }
  1995.     }
  1996. }
  1997.  
  1998. template <class BidirectionalIterator1, class BidirectionalIterator2,
  1999.                                             class BidirectionalIterator3, class Compare>
  2000. BidirectionalIterator3 __merge_backward(BidirectionalIterator1 first1,
  2001.                                         BidirectionalIterator1 last1,
  2002.                                         BidirectionalIterator2 first2,
  2003.                                         BidirectionalIterator2 last2,
  2004.                                         BidirectionalIterator3 result,
  2005.                                         Compare comp) {
  2006.     if (first1 == last1) return copy_backward(first2, last2, result);
  2007.     if (first2 == last2) return copy_backward(first1, last1, result);
  2008.     --last1;
  2009.     --last2;
  2010.     while (true) {
  2011.         if (comp(*last2, *last1)) {
  2012.             *--result = *last1;
  2013.             if (first1 == last1) return copy_backward(first2, ++last2, result);
  2014.             --last1;
  2015.         } else {
  2016.             *--result = *last2;
  2017.             if (first2 == last2) return copy_backward(first1, ++last1, result);
  2018.             --last2;
  2019.         }
  2020.     }
  2021. }
  2022.  
  2023. template <class BidirectionalIterator, class Distance, class T>
  2024. void __merge_adaptive(BidirectionalIterator first, 
  2025.                       BidirectionalIterator middle, 
  2026.                       BidirectionalIterator last, Distance len1, Distance len2,
  2027.                       __stl_tempbuf<T,Distance>& buffer) {
  2028.     typedef typename  __stl_tempbuf<T,Distance>::pointer Pointer;
  2029.     if (len1 <= len2 && len1 <= buffer.capacity()) {
  2030.         Pointer end_buffer = copy(first, middle, buffer.begin());
  2031.         merge(buffer.begin(), end_buffer, middle, last, first);
  2032.     } else if (len2 <= buffer.capacity()) {
  2033.         Pointer end_buffer = copy(middle, last, buffer.begin());
  2034.         __merge_backward(first, middle, buffer.begin(), end_buffer, last);
  2035.     } else {
  2036.         BidirectionalIterator first_cut = first;
  2037.         BidirectionalIterator second_cut = middle;
  2038.         Distance len11 = 0;
  2039.         Distance len22 = 0;
  2040.         if (len1 > len2) {
  2041.             len11 = len1 / 2;
  2042.             advance(first_cut, len11);
  2043.             second_cut = lower_bound(middle, last, *first_cut);
  2044.             distance(middle, second_cut, len22);   
  2045.         } else {
  2046.             len22 = len2 / 2;
  2047.             advance(second_cut, len22);
  2048.             first_cut = upper_bound(first, middle, *second_cut);
  2049.             distance(first, first_cut, len11);
  2050.         }
  2051.         BidirectionalIterator new_middle =
  2052.             __rotate_adaptive(first_cut, middle, second_cut, len1 - len11,
  2053.                               len22, buffer.begin(), buffer.capacity());
  2054.         __merge_adaptive(first, first_cut, new_middle, len11, len22, buffer);
  2055.         __merge_adaptive(new_middle, second_cut, last, len1 - len11,
  2056.                          len2 - len22, buffer);
  2057.     }
  2058. }
  2059.  
  2060. template <class BidirectionalIterator, class Distance, class T,
  2061.                           class Compare>
  2062. void __merge_adaptive(BidirectionalIterator first, 
  2063.                       BidirectionalIterator middle, 
  2064.                       BidirectionalIterator last, Distance len1, Distance len2,
  2065.                       __stl_tempbuf<T,Distance>& buffer, Compare comp) {
  2066.     typedef typename  __stl_tempbuf<T,Distance>::pointer Pointer;
  2067.     if (len1 <= len2 && len1 <= buffer.capacity()) {
  2068.         Pointer end_buffer = copy(first, middle, buffer.begin());
  2069.         merge(buffer.begin(), end_buffer, middle, last, first, comp);
  2070.     } else if (len2 <= buffer.capacity()) {
  2071.         Pointer end_buffer = copy(middle, last, buffer.begin());
  2072.         __merge_backward(first, middle, buffer.begin(), end_buffer, last, comp);
  2073.     } else {
  2074.         BidirectionalIterator first_cut = first;
  2075.         BidirectionalIterator second_cut = middle;
  2076.         Distance len11 = 0;
  2077.         Distance len22 = 0;
  2078.         if (len1 > len2) {
  2079.             len11 = len1 / 2;
  2080.             advance(first_cut, len11);
  2081.             second_cut = lower_bound(middle, last, *first_cut, comp);
  2082.             distance(middle, second_cut, len22);   
  2083.         } else {
  2084.             len22 = len2 / 2;
  2085.             advance(second_cut, len22);
  2086.             first_cut = upper_bound(first, middle, *second_cut, comp);
  2087.             distance(first, first_cut, len11);
  2088.         }
  2089.         BidirectionalIterator new_middle =
  2090.             __rotate_adaptive(first_cut, middle, second_cut, len1 - len11,
  2091.                               len22, buffer.begin(), buffer.capacity());
  2092.         __merge_adaptive(first, first_cut, new_middle, len11, len22, buffer,comp);
  2093.         __merge_adaptive(new_middle, second_cut, last, len1 - len11,
  2094.                          len2 - len22, buffer, comp);
  2095.     }
  2096. }
  2097.  
  2098. template <class BidirectionalIterator, class Distance, class T>
  2099. void __inplace_merge(BidirectionalIterator first,
  2100.                      BidirectionalIterator middle, 
  2101.                      BidirectionalIterator last, Distance len1, Distance len2,
  2102.                      __stl_tempbuf<T,Distance>& buffer) {
  2103.     if (buffer.capacity() == 0) {
  2104.         __merge_without_buffer(first, middle, last, len1, len2);
  2105.     }
  2106.     else {
  2107.         Distance len(len1+len2); // VC++ temporary ref warning
  2108.         len = min(buffer.capacity(), len);
  2109.         __default_initialize_n(buffer.begin(), len);
  2110. //        uninitialized_fill_n(buffer.begin(), len, *first);
  2111.         buffer.adjust_size(len);
  2112.         __merge_adaptive(first, middle, last, len1, len2, buffer);
  2113.     }
  2114. }
  2115.  
  2116. template <class BidirectionalIterator, class Distance, class T,
  2117.                          class Compare>
  2118. void __inplace_merge(BidirectionalIterator first,
  2119.                      BidirectionalIterator middle, 
  2120.                      BidirectionalIterator last, Distance len1, Distance len2,
  2121.                      __stl_tempbuf<T,Distance>& buffer, Compare comp) {
  2122.     if (buffer.capacity() == 0) {
  2123.         __merge_without_buffer(first, middle, last, len1, len2, comp);
  2124.     }
  2125.     else {
  2126.         Distance len(len1+len2);
  2127.         len = min(buffer.capacity(), len);
  2128.         __default_initialize_n(buffer.begin(), len);
  2129. //        uninitialized_fill_n(buffer.begin(), len, *first);
  2130.         buffer.adjust_size(len);
  2131.         __merge_adaptive(first, middle, last, len1, len2, buffer,comp); 
  2132.     }
  2133. }
  2134.  
  2135. template <class BidirectionalIterator, class T, class Distance>
  2136. inline void __inplace_merge_aux(BidirectionalIterator first,
  2137.                                 BidirectionalIterator middle,
  2138.                                 BidirectionalIterator last, T*, Distance*) {
  2139.     Distance len1 = 0;
  2140.     distance(first, middle, len1);
  2141.     Distance len2 = 0;
  2142.     distance(middle, last, len2);
  2143.     __stl_tempbuf<T,Distance> buf(len1 + len2);
  2144.     __inplace_merge(first, middle, last, len1, len2, buf);
  2145. }
  2146.  
  2147. template <class BidirectionalIterator, class T, class Distance, class Compare>
  2148. inline void __inplace_merge_aux(BidirectionalIterator first,
  2149.                                 BidirectionalIterator middle,
  2150.                                 BidirectionalIterator last, T*, Distance*,
  2151.                                 Compare comp) {
  2152.     Distance len1 = 0;
  2153.     distance(first, middle, len1);
  2154.     Distance len2 = 0;
  2155.     distance(middle, last, len2);
  2156.     __stl_tempbuf<T,Distance> buf(len1 + len2);
  2157.     __inplace_merge(first, middle, last, len1, len2, buf, comp);
  2158. }
  2159.  
  2160. template <class BidirectionalIterator>
  2161. inline void inplace_merge(BidirectionalIterator first,
  2162.                           BidirectionalIterator middle,
  2163.                           BidirectionalIterator last) {
  2164.     __stl_debug_check(__check_range(middle, first, last));
  2165.     if (first == middle || middle == last) return;
  2166.     __inplace_merge_aux(first, middle, last, value_type(first),
  2167.                         distance_type(first));
  2168. }
  2169.  
  2170. template <class BidirectionalIterator, class Compare>
  2171. inline void inplace_merge(BidirectionalIterator first,
  2172.                           BidirectionalIterator middle,
  2173.                           BidirectionalIterator last, Compare comp) {
  2174.     __stl_debug_check(__check_range(middle, first, last));
  2175.     if (first == middle || middle == last) return;
  2176.     __inplace_merge_aux(first, middle, last, value_type(first),
  2177.                         distance_type(first), comp);
  2178. }
  2179.  
  2180. template <class InputIterator1, class InputIterator2>
  2181. bool includes(InputIterator1 first1, InputIterator1 last1,
  2182.               InputIterator2 first2, InputIterator2 last2) {
  2183.     __stl_debug_check(__check_range(first1, last1));
  2184.     __stl_debug_check(__check_range(first2, last2));
  2185.     while (first1 != last1 && first2 != last2)
  2186.         if (*first2 < *first1)
  2187.             return false;
  2188.         else if(*first1 < *first2) 
  2189.             ++first1;
  2190.         else
  2191.             ++first1, ++first2;
  2192.  
  2193.     return first2 == last2;
  2194. }
  2195.  
  2196. template <class InputIterator1, class InputIterator2, class Compare>
  2197. bool includes(InputIterator1 first1, InputIterator1 last1,
  2198.               InputIterator2 first2, InputIterator2 last2, Compare comp) {
  2199.     __stl_debug_check(__check_range(first1, last1));
  2200.     __stl_debug_check(__check_range(first2, last2));
  2201.     while (first1 != last1 && first2 != last2)
  2202.         if (comp(*first2, *first1))
  2203.             return false;
  2204.         else if(comp(*first1, *first2)) 
  2205.             ++first1;
  2206.         else
  2207.             ++first1, ++first2;
  2208.  
  2209.     return first2 == last2;
  2210. }
  2211.  
  2212. template <class InputIterator1, class InputIterator2, class OutputIterator>
  2213. OutputIterator set_union(InputIterator1 first1, InputIterator1 last1,
  2214.                          InputIterator2 first2, InputIterator2 last2,
  2215.                          OutputIterator result) {
  2216.     __stl_debug_check(__check_range(first1, last1));
  2217.     __stl_debug_check(__check_range(first2, last2));
  2218. //    __stl_debug_check(__check_not_range(result,first1, last1));
  2219.     for (; first1 != last1 && first2 != last2; ++result)
  2220.         if (*first1 < *first2) {
  2221.             *result = *first1; ++first1;
  2222.         }
  2223.         else if (*first2 < *first1) {
  2224.             *result = *first2; ++first2;
  2225.         }
  2226.         else {
  2227.             *result = *first1++;
  2228.             ++first2;
  2229.         }
  2230.     return copy(first2, last2, copy(first1, last1, result));
  2231. }
  2232.  
  2233. template <class InputIterator1, class InputIterator2, class OutputIterator,
  2234.                              class Compare>
  2235. OutputIterator set_union(InputIterator1 first1, InputIterator1 last1,
  2236.                          InputIterator2 first2, InputIterator2 last2,
  2237.                          OutputIterator result, Compare comp) {
  2238.     __stl_debug_check(__check_range(first1, last1));
  2239.     __stl_debug_check(__check_range(first2, last2));
  2240.     for (; first1 != last1 && first2 != last2; ++result)
  2241.         if (comp(*first1, *first2)) {
  2242.             *result = *first1; ++first1;
  2243.         }
  2244.         else if (comp(*first2, *first1)) {
  2245.             *result = *first2; ++first2;
  2246.         }
  2247.         else {
  2248.             *result = *first1;
  2249.             ++first1;
  2250.             ++first2;
  2251.         }
  2252.     return copy(first2, last2, copy(first1, last1, result));
  2253. }
  2254.  
  2255. template <class InputIterator1, class InputIterator2, class OutputIterator>
  2256. OutputIterator set_intersection(InputIterator1 first1, InputIterator1 last1,
  2257.                                 InputIterator2 first2, InputIterator2 last2,
  2258.                                 OutputIterator result) {
  2259.     __stl_debug_check(__check_range(first1, last1));
  2260.     __stl_debug_check(__check_range(first2, last2));
  2261.     while (first1 != last1 && first2 != last2)
  2262.         if (*first1 < *first2)
  2263.             ++first1;
  2264.         else if (*first2 < *first1)
  2265.             ++first2;
  2266.         else {
  2267.             *result = *first1;
  2268.             ++result;
  2269.             ++first1;
  2270.             ++first2;
  2271.         }
  2272.     return result;
  2273. }
  2274.  
  2275. template <class InputIterator1, class InputIterator2, class OutputIterator,
  2276.                                     class Compare>
  2277. OutputIterator set_intersection(InputIterator1 first1, InputIterator1 last1,
  2278.                                 InputIterator2 first2, InputIterator2 last2,
  2279.                                 OutputIterator result, Compare comp) {
  2280.     __stl_debug_check(__check_range(first1, last1));
  2281.     __stl_debug_check(__check_range(first2, last2));
  2282.     while (first1 != last1 && first2 != last2)
  2283.         if (comp(*first1, *first2))
  2284.             ++first1;
  2285.         else if (comp(*first2, *first1))
  2286.             ++first2;
  2287.         else {
  2288.             *result = *first1;
  2289.             ++first2;
  2290.             ++result;
  2291.             ++first1;
  2292.         }
  2293.     return result;
  2294. }
  2295.  
  2296. template <class InputIterator1, class InputIterator2, class OutputIterator>
  2297. OutputIterator set_difference(InputIterator1 first1, InputIterator1 last1,
  2298.                               InputIterator2 first2, InputIterator2 last2,
  2299.                               OutputIterator result) {
  2300.     __stl_debug_check(__check_range(first1, last1));
  2301.     __stl_debug_check(__check_range(first2, last2));
  2302.     while (first1 != last1 && first2 != last2)
  2303.         if (*first1 < *first2) {
  2304.             *result = *first1;
  2305.             ++result;
  2306.             ++first1;
  2307.         }
  2308.         else if (*first2 < *first1)
  2309.             ++first2;
  2310.         else {
  2311.             ++first1;
  2312.             ++first2;
  2313.         }
  2314.     return copy(first1, last1, result);
  2315. }
  2316.  
  2317. template <class InputIterator1, class InputIterator2, class OutputIterator, 
  2318.                                   class Compare>
  2319. OutputIterator set_difference(InputIterator1 first1, InputIterator1 last1,
  2320.                               InputIterator2 first2, InputIterator2 last2, 
  2321.                               OutputIterator result, Compare comp) {
  2322.     __stl_debug_check(__check_range(first1, last1));
  2323.     __stl_debug_check(__check_range(first2, last2));
  2324.     while (first1 != last1 && first2 != last2)
  2325.         if (comp(*first1, *first2)) {
  2326.             *result = *first1;
  2327.             ++result;
  2328.             ++first1;
  2329.         }
  2330.         else if (comp(*first2, *first1))
  2331.             ++first2;
  2332.         else {
  2333.             ++first1;
  2334.             ++first2;
  2335.         }
  2336.     return copy(first1, last1, result);
  2337. }
  2338.  
  2339. template <class InputIterator1, class InputIterator2, class OutputIterator>
  2340. OutputIterator set_symmetric_difference(InputIterator1 first1,
  2341.                                         InputIterator1 last1,
  2342.                                         InputIterator2 first2,
  2343.                                         InputIterator2 last2,
  2344.                                         OutputIterator result) {
  2345.     __stl_debug_check(__check_range(first1, last1));
  2346.     __stl_debug_check(__check_range(first2, last2));
  2347.     while (first1 != last1 && first2 != last2)
  2348.         if (*first1 < *first2) {
  2349.             *result = *first1;
  2350.             ++result;
  2351.             ++first1;
  2352.         }
  2353.         else if (*first2 < *first1)  {
  2354.             *result = *first2;
  2355.             ++result;
  2356.             ++first2;
  2357.         }
  2358.         else {
  2359.             ++first1;
  2360.             ++first2;
  2361.         }
  2362.     return copy(first2, last2, copy(first1, last1, result));
  2363. }
  2364.  
  2365. template <class InputIterator1, class InputIterator2, class OutputIterator,
  2366.                                             class Compare>
  2367. OutputIterator set_symmetric_difference(InputIterator1 first1,
  2368.                                         InputIterator1 last1,
  2369.                                         InputIterator2 first2,
  2370.                                         InputIterator2 last2,
  2371.                                         OutputIterator result, Compare comp) {
  2372.     __stl_debug_check(__check_range(first1, last1));
  2373.     __stl_debug_check(__check_range(first2, last2));
  2374.     while (first1 != last1 && first2 != last2)
  2375.         if (comp(*first1, *first2))  {
  2376.             *result = *first1;
  2377.             ++result;
  2378.             ++first1;
  2379.         }
  2380.         else if (comp(*first2, *first1)) {
  2381.             *result = *first2;
  2382.             ++result;
  2383.             ++first2;
  2384.         }
  2385.         else {
  2386.             ++first1;
  2387.             ++first2;
  2388.         }
  2389.     return copy(first2, last2, copy(first1, last1, result));
  2390. }
  2391.  
  2392. template <class ForwardIterator>
  2393. ForwardIterator max_element(ForwardIterator first, ForwardIterator last) {
  2394.     __stl_debug_check(__check_range(first, last));
  2395.     if (first == last) return first;
  2396.     ForwardIterator result = first;
  2397.     while (++first != last) 
  2398.         if (*result < *first) result = first;
  2399.     return result;
  2400. }
  2401.  
  2402. template <class ForwardIterator, class Compare>
  2403. ForwardIterator max_element(ForwardIterator first, ForwardIterator last,
  2404.                             Compare comp) {
  2405.     __stl_debug_check(__check_range(first, last));
  2406.     if (first == last) return first;
  2407.     ForwardIterator result = first;
  2408.     while (++first != last) 
  2409.         if (comp(*result, *first)) result = first;
  2410.     return result;
  2411. }
  2412.  
  2413. template <class ForwardIterator>
  2414. ForwardIterator min_element(ForwardIterator first, ForwardIterator last) {
  2415.     __stl_debug_check(__check_range(first, last));
  2416.     if (first == last) return first;
  2417.     ForwardIterator result = first;
  2418.     while (++first != last) 
  2419.         if (*first < *result) result = first;
  2420.     return result;
  2421. }
  2422.  
  2423. template <class ForwardIterator, class Compare>
  2424. ForwardIterator min_element(ForwardIterator first, ForwardIterator last,
  2425.                             Compare comp) {
  2426.     __stl_debug_check(__check_range(first, last));
  2427.     if (first == last) return first;
  2428.     ForwardIterator result = first;
  2429.     while (++first != last) 
  2430.         if (comp(*first, *result)) result = first;
  2431.     return result;
  2432. }
  2433.  
  2434. template <class BidirectionalIterator>
  2435. bool next_permutation(BidirectionalIterator first,
  2436.                       BidirectionalIterator last) {
  2437.     __stl_debug_check(__check_range(first, last));
  2438.     if (first == last) return false;
  2439.     BidirectionalIterator i = first;
  2440.     ++i;
  2441.     if (i == last) return false;
  2442.     i = last;
  2443.     --i;
  2444.  
  2445.     for(;;) {
  2446.         BidirectionalIterator ii = i;
  2447.         if (*--i < *ii) {
  2448.             BidirectionalIterator j = last;
  2449.             while (!(*i < *--j));
  2450.             iter_swap(i, j);
  2451.             reverse(ii, last);
  2452.             return true;
  2453.         }
  2454.         if (i == first) {
  2455.             reverse(first, last);
  2456.             return false;
  2457.         }
  2458.     }
  2459. }
  2460.  
  2461. template <class BidirectionalIterator, class Compare>
  2462. bool next_permutation(BidirectionalIterator first, BidirectionalIterator last,
  2463.                       Compare comp) {
  2464.     __stl_debug_check(__check_range(first, last));
  2465.     if (first == last) return false;
  2466.     BidirectionalIterator i = first;
  2467.     ++i;
  2468.     if (i == last) return false;
  2469.     i = last;
  2470.     --i;
  2471.  
  2472.     for(;;) {
  2473.         BidirectionalIterator ii = i ; 
  2474.         if (comp(*--i, *ii)) {
  2475.             BidirectionalIterator j = last;
  2476.             while (!comp(*i, *--j));
  2477.             iter_swap(i, j);
  2478.             reverse(ii, last);
  2479.             return true;
  2480.         }
  2481.         if (i == first) {
  2482.             reverse(first, last);
  2483.             return false;
  2484.         }
  2485.     }
  2486. }
  2487.  
  2488. template <class BidirectionalIterator>
  2489. bool prev_permutation(BidirectionalIterator first,
  2490.                       BidirectionalIterator last) {
  2491.     __stl_debug_check(__check_range(first, last));
  2492.     if (first == last) return false;
  2493.     BidirectionalIterator i = first;
  2494.     ++i;
  2495.     if (i == last) return false;
  2496.     i = last;
  2497.     --i;
  2498.  
  2499.     for(;;) {
  2500.         BidirectionalIterator ii = i; 
  2501.         if (*ii < *--i) {
  2502.             BidirectionalIterator j = last;
  2503.             while (!(*--j < *i));
  2504.             iter_swap(i, j);
  2505.             reverse(ii, last);
  2506.             return true;
  2507.         }
  2508.         if (i == first) {
  2509.             reverse(first, last);
  2510.             return false;
  2511.         }
  2512.     }
  2513. }
  2514.  
  2515. template <class BidirectionalIterator, class Compare>
  2516. bool prev_permutation(BidirectionalIterator first, BidirectionalIterator last,
  2517.                       Compare comp) {
  2518.     __stl_debug_check(__check_range(first, last));
  2519.     if (first == last) return false;
  2520.     BidirectionalIterator i = first;
  2521.     ++i;
  2522.     if (i == last) return false;
  2523.     i = last;
  2524.     --i;
  2525.  
  2526.     for(;;) {
  2527.         BidirectionalIterator ii = i;
  2528.         if (comp(*ii, *--i)) {
  2529.             BidirectionalIterator j = last;
  2530.             while (!comp(*--j, *i));
  2531.             iter_swap(i, j);
  2532.             reverse(ii, last);
  2533.             return true;
  2534.         }
  2535.         if (i == first) {
  2536.             reverse(first, last);
  2537.             return false;
  2538.         }
  2539.     }
  2540. }
  2541.  
  2542. template <class InputIterator, class T>
  2543. T accumulate(InputIterator first, InputIterator last, T init) {
  2544.     __stl_debug_check(__check_range(first, last));
  2545.     for (; first != last ; ++first) 
  2546.         init = init + *first;
  2547.     return init;
  2548. }
  2549.  
  2550. template <class InputIterator, class T, class BinaryOperation>
  2551. T accumulate(InputIterator first, InputIterator last, T init,
  2552.              BinaryOperation binary_op) {
  2553.     __stl_debug_check(__check_range(first, last));
  2554.     for (; first != last ; ++first) 
  2555.         init = binary_op(init, *first);
  2556.     return init;
  2557. }
  2558.  
  2559. template <class InputIterator1, class InputIterator2, class T>
  2560. T inner_product(InputIterator1 first1, InputIterator1 last1,
  2561.                 InputIterator2 first2, T init) {
  2562.     __stl_debug_check(__check_range(first1, last1));
  2563.     for (; first1 != last1; ++first1,++first2) 
  2564.         init = init + (*first1 * *first2);
  2565.     return init;
  2566. }
  2567.  
  2568. template <class InputIterator1, class InputIterator2, class T,
  2569.                     class BinaryOperation1, class BinaryOperation2>
  2570. T inner_product(InputIterator1 first1, InputIterator1 last1,
  2571.                 InputIterator2 first2, T init, BinaryOperation1 binary_op1,
  2572.                 BinaryOperation2 binary_op2) {
  2573.     __stl_debug_check(__check_range(first1, last1));
  2574.     for (; first1 != last1; ++first1,++first2) 
  2575.         init = binary_op1(init, binary_op2(*first1, *first2));
  2576.     return init;
  2577. }
  2578.  
  2579. template <class InputIterator, class OutputIterator, class T>
  2580. INLINE_LOOP OutputIterator __partial_sum(InputIterator first, InputIterator last,
  2581.                                          OutputIterator result, T*) {
  2582.     T value = *first;
  2583.     while (++first != last) {
  2584.         value = value + *first;
  2585.         *++result = value;
  2586.     }
  2587.     return ++result;
  2588. }
  2589.  
  2590. template <class InputIterator, class OutputIterator>
  2591. OutputIterator partial_sum(InputIterator first, InputIterator last,
  2592.                            OutputIterator result) {
  2593.     __stl_debug_check(__check_range(first, last));
  2594.     if (first == last) return result;
  2595.     *result = *first;
  2596.     return __partial_sum(first, last, result, value_type(first));
  2597. }
  2598.  
  2599. template <class InputIterator, class OutputIterator, class T,
  2600.                                class BinaryOperation>
  2601. INLINE_LOOP OutputIterator __partial_sum(InputIterator first, InputIterator last,
  2602.                                          OutputIterator result, T*,
  2603.                                          BinaryOperation binary_op) {
  2604.     T value = *first;
  2605.     while (++first != last) {
  2606.         value = binary_op(value, *first);
  2607.         *++result = value;
  2608.     }
  2609.     return ++result;
  2610. }
  2611.  
  2612. template <class InputIterator, class OutputIterator, class BinaryOperation>
  2613. OutputIterator partial_sum(InputIterator first, InputIterator last,
  2614.                            OutputIterator result, BinaryOperation binary_op) {
  2615.     __stl_debug_check(__check_range(first, last));
  2616.     if (first == last) return result;
  2617.     *result = *first;
  2618.     return __partial_sum(first, last, result, value_type(first), binary_op);
  2619. }
  2620.  
  2621. template <class InputIterator, class OutputIterator, class T>
  2622. INLINE_LOOP OutputIterator __adjacent_difference(InputIterator first, InputIterator last, 
  2623.                                                  OutputIterator result, T*) {
  2624.     T value = *first;
  2625.     while (++first != last) {
  2626.         T tmp = *first;
  2627.         *++result = tmp - value;
  2628.         value = tmp;
  2629.     }
  2630.     return ++result;
  2631. }
  2632.  
  2633. template <class InputIterator, class OutputIterator>
  2634. OutputIterator adjacent_difference(InputIterator first, InputIterator last, 
  2635.                                    OutputIterator result) {
  2636.     __stl_debug_check(__check_range(first, last));
  2637.     if (first == last) return result;
  2638.     *result = *first;
  2639.     return __adjacent_difference(first, last, result, value_type(first));
  2640. }
  2641.  
  2642. template <class InputIterator, class OutputIterator, class T, 
  2643.                                        class BinaryOperation>
  2644. INLINE_LOOP OutputIterator __adjacent_difference(InputIterator first, InputIterator last, 
  2645.                                                  OutputIterator result, T*,
  2646.                                                  BinaryOperation binary_op) {
  2647.     T value = *first;
  2648.     while (++first != last) {
  2649.         T tmp = *first;
  2650.         *++result = binary_op(tmp, value);
  2651.         value = tmp;
  2652.     }
  2653.     return ++result;
  2654. }
  2655.  
  2656. template <class InputIterator, class OutputIterator, class BinaryOperation>
  2657. OutputIterator adjacent_difference(InputIterator first, InputIterator last,
  2658.                                    OutputIterator result,
  2659.                                    BinaryOperation binary_op) {
  2660.     __stl_debug_check(__check_range(first, last));
  2661.     if (first == last) return result;
  2662.     *result = *first;
  2663.     return __adjacent_difference(first, last, result, value_type(first),
  2664.                                  binary_op);
  2665. }
  2666.  
  2667. template <class ForwardIterator, class T>
  2668. void iota(ForwardIterator first, ForwardIterator last, T value) {
  2669.     __stl_debug_check(__check_range(first, last));
  2670.     for (; first != last; ++first,++value) *first = value;
  2671. }
  2672.  
  2673. template <class RandomAccessIterator, class Distance>
  2674. bool __is_heap(RandomAccessIterator first, RandomAccessIterator last,
  2675.                Distance*)
  2676. {
  2677.     const Distance n = last - first;
  2678.  
  2679.     Distance parent = 0;
  2680.     for (Distance child = 1; child < n; ++child) {
  2681.         if (first[parent] < first[child]) 
  2682.             return false;
  2683.         if (child % 2 == 0)
  2684.             ++parent;
  2685.     }
  2686.     return true;
  2687. }
  2688.  
  2689. template <class RandomAccessIterator>
  2690. inline bool is_heap(RandomAccessIterator first, RandomAccessIterator last)
  2691. {
  2692.     __stl_debug_check(__check_range(first, last));
  2693.     return __is_heap(first, last, distance_type(first));
  2694. }
  2695.  
  2696.  
  2697. template <class RandomAccessIterator, class Distance, class StrictWeakOrdering>
  2698. bool __is_heap(RandomAccessIterator first, RandomAccessIterator last,
  2699.                StrictWeakOrdering comp,
  2700.                Distance*)
  2701. {
  2702.     const Distance n = last - first;
  2703.  
  2704.     Distance parent = 0;
  2705.     for (Distance child = 1; child < n; ++child) {
  2706.         if (comp(first[parent], first[child]))
  2707.             return false;
  2708.         if (child % 2 == 0)
  2709.             ++parent;
  2710.     }
  2711.     return true;
  2712. }
  2713.  
  2714. template <class RandomAccessIterator, class StrictWeakOrdering>
  2715. inline bool is_heap(RandomAccessIterator first, RandomAccessIterator last,
  2716.                     StrictWeakOrdering comp)
  2717. {
  2718.     __stl_debug_check(__check_range(first, last));
  2719.     return __is_heap(first, last, comp, distance_type(first));
  2720. }
  2721.  
  2722.  
  2723. template <class ForwardIterator>
  2724. bool is_sorted(ForwardIterator first, ForwardIterator last)
  2725. {
  2726.     __stl_debug_check(__check_range(first, last));
  2727.     if (first == last)
  2728.         return true;
  2729.  
  2730.     ForwardIterator next = first;
  2731.     for (++next; next != last; first = next, ++next) {
  2732.         if (*next < *first)
  2733.             return false;
  2734.     }
  2735.  
  2736.     return true;
  2737. }
  2738.  
  2739. template <class ForwardIterator, class StrictWeakOrdering>
  2740. bool is_sorted(ForwardIterator first, ForwardIterator last,
  2741.                StrictWeakOrdering comp)
  2742. {
  2743.     __stl_debug_check(__check_range(first, last));
  2744.     if (first == last)
  2745.         return true;
  2746.  
  2747.     ForwardIterator next = first;
  2748.     for (++next; next != last; first = next, ++next) {
  2749.         if (comp(*next, *first))
  2750.             return false;
  2751.     }
  2752.  
  2753.     return true;
  2754. }
  2755.  
  2756. # undef __stl_threshold
  2757. __END_STL_NAMESPACE
  2758.  
  2759. #endif
  2760.  
  2761.